A couple of gems allow the easy daemonisation of scripts / long running processes. But as soon as you need to include your Rails environment you might run into problems.

The problem

Take this script for example (which lives in script/ruote_worker.rb):


  require 'daemons'
  require File.expand_path(File.join(File.dirname(__FILE__),
  	'..', 'config', 'environment'))

  Daemons.run_proc('ruote_worker') do
    RuoteKit.run_worker(RuoteSetup.ruote_storage)
  end	

Looks pretty straightforward - The daemons gem provides a run_proc method which daemonises the given block. But as soon as the ruote worker tries to write something to the log-file we get an IOError: closed stream exception.

Rails 3 wants the log file to itself

After some research it seems like Rails doesn't like it, when multiple processes have a handle on the log file(s). As the response in the linked question correctly points out, the solution is to instantiate a new logger... with one addition: If your process is using ActiveRecord, we need to re-assign the ActiveRecord.logger as well:


  require 'daemons'
  require File.expand_path(File.join(File.dirname(__FILE__),
  	'..', 'config', 'environment'))
  require 'ruote/part/smtp_participant'

  Daemons.run_proc('ruote_worker') do
    ruote_logger = ActiveSupport::BufferedLogger.new(
    	File.join(Rails.root, "log", "ruote_worker.log"))
    Rails.logger = ruote_logger
    ActiveRecord::Base.logger = ruote_logger
  
    RuoteKit.run_worker(RuoteSetup.ruote_storage)
  end