Keeping Rails running at Dreamhost Part 2

Update 2/2/07: Per Thomas’ comment I’ve released the code below as the dreamhost rails plugin.
Update 1/25/07: People have reported difficulties copy and pasting the dispatch.fcgi source code from this blog post so here is a dispatch.fcgi to download. Make sure you make it executable!

My first attempt to keep my Ruby on Rails sites running at Dreamhost involved modifying dispatch.fcgi to implement the frao_handler approach as described on the wiki. This left me with a 3% 500 error rate. Ughh!

My second attempt involved gracefully restarting dispatch.fcgi’s every hour or two to avoid the wrath of the Dreamhost process monitor. This reduced the 500 error rate down to 0.2% which was still too high!

I’ve finally gotten my 500 error rate down to 0 by making some minor changes to the signal handling code of dispatch.fcgi. If the dispatch.fcgi process is in the midst of handling a request I defer letting it be killed until the request is complete. I did this by installing a custom TERM signal handler that protects the dispatch.fcgi process while a request is being processed. This solution works for my Rails 1.1 and Rails 1.2 (previously Edge) based sites. Here’s my complete dispatch.fcgi:

#!/usr/bin/ruby1.8

require File.dirname(__FILE__) + "/../config/environment"
require 'fcgi_handler'

class RailsFCGIHandler
 private
   def busy_exit_handler(signal)
     dispatcher_log :info, "busy: asked to terminate during request signal #{signal}, deferring!"
     @when_ready = :exit
   end

   # Dreamhost sends the term signal and if we're handling a request defer it
   def term_process_request(cgi)
     install_signal_handler('TERM',method(:busy_exit_handler).to_proc)
     Dispatcher.dispatch(cgi)
   rescue Exception => e  # errors from CGI dispatch
     raise if SignalException === e
     dispatcher_error(e)
   ensure
     install_signal_handler('TERM', method(:exit_now_handler).to_proc)
   end
   alias_method :process_request, :term_process_request
end

RailsFCGIHandler.process!
This entry was posted in Linux, Ruby, Ruby on Rails, Systems Administration, Web. Bookmark the permalink.