One of the great things about Gemcutter is that it’s using Sinatra via Rails Metal to serve up the gems. Recently, I had to run some long migrations (~10 minutes) and I’m sure we’ll have some more in the future. Since the gem server is decoupled from the Rails app, some clever Rack loading now allows us to continue to serve gems even when we’re down for maintenance.
config.ru now looks like this:
if ENV['MAINTENANCE_MODE'] require File.join('vendor', 'bundler_gems', 'environment') require File.join('config', 'environment') use Rack::Static, :urls => ["/index.html", "/favicon.ico", "/images", "/stylesheets"], :root => "public/maintenance" use Hostess use Rack::Maintenance, :file => File.join('public', 'maintenance', 'index.html') run Sinatra::Application else require 'thin' run Rack::Adapter::Rails.new(:environment => ENV['RAILS_ENV']) end
So now, Heroku treats Gemcutter as a Rack app, and not a pure Rails app. Normally, it’ll just use Thin and boot up Rails as normal with
script/server still works as normal, too, but I’ll probably use shotgun instead.
The fun begins when you run
MAINTENANCE_MODE=on rackup. The following happens from there:
- Load up the Bundler environment that has all of our gems, and some of Rails’ magic.
- Fire up Rack::Static to serve static assets like the images and CSS to make the site look nice
- Use the Hostess, Gemcutter’s Sinatra gem server to continue to serve gems
- All other requests are then caught by David Dollar’s rack-maintenance that simply serves up a static HTML page.
Sinatra::Applicationsince we need some sort of endpoint.
And boom, we have a read-only site that continues to serve gems. Rack rules.