trotzig/diffux — pull request #48 by ted27 (2014-02-09 07:57:17+00:00)
Title: Add compatibility with Heroku

Okay, this was a bit of a "for fun" kind of thing, so I would totally understand if you don't want to merge this. But I want to actually use Diffux for my personal projects, so I'm going to work on a hosted instance and a Github post-receive hook setup that will automatically snapshot.

Anyway, check it out at: http://diffux.herokuapp.com/ (feel free to add your own sites to it)

The Heroku platform presents a number of challenges, mostly stemming from the fact that Heroku is designed to be a read-only filesystem (with a /tmp directory that is emptied relatively frequently). This has a couple ramifications:
* We have to use Paperclip + S3 for Snapshot image persistence
* Since there is no clean Paperclip::Attachment abstraction for the binary "image data", the `SnapshotComparer` will have to know how to fetch the snapshots from S3 or the local filesystem, depending on which is used
* The PhantomJS gem typically downloads the binary the first time it is used. There is a clever way to make Heroku download the binary at build time and then I wrote a shim ("platform") which uses it.

There is also one other practical consideration: **running a sidekiq worker will cost $37/month**. So, I wrote an overly clever `HerokuManager` service which kills the delayed worker thread if no workers are doing anything. The Snapshot after_commit callback starts the thread as it enqueues the snapshots to be processed. To take two snapshots, the whole process takes < 30 seconds. Unfortunately, I couldn't think of a better way to detect when the workers are idle than something on every pageview. (Thoughts?)

That's about it! I snuck one minor change in here regarding a migration that botched my clean-slate run of `rake db:migrate` and also wrote up everything I did on Heroku in the README. Let me know what you think.

Cheers!