Daemonize a script or worker in Rails 3
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
