Daemonizing a Ruby Script in Rails

This took way longer than it should have, so I thought I’d jot down what I did so it might take less time next time.

1. Install the daemons gem

sudo gem install daemons

2. Presumably you have a script that looks something like this already

#!/usr/bin/env ruby
require File.dirname(__FILE__) + "/. ./config/environment"
 
SchedulerDaemon.new.run

This is a scheduler script that lives in the scripts directory of a rails project.

3. You’re going to take this code and wrap it in daemon stuff, like so

#!/usr/bin/env ruby
RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/. .')
 
require 'rubygems'
gem 'daemons'
require 'daemons'
 
Daemons.run_proc("scheduler", 
                 :log_output => true, 
                 :dir_mode => :normal, 
                 :dir => "#{RAILS_ROOT}/log") do
  require File.join(RAILS_ROOT, "config/environment")
  SchedulerDaemon.new.run
end

The really hard part for me was debugging it. Which meant figuring out how to get logging going. With this code, you can just tail “log/scheduler.output” and see the contents of any puts in the code. Once I started doing that, everything else was easy.

RAILS_ROOT has to be set first, because daemons changes the current working directory. Also, I use the log dir, because it’s shared by capistrano, so I can deploy, then stop / start my scheduler and not worry about losing my first pid file – plus that’s where logs are supposed to go.

4. To make my life just a little easier, I also added some debugging statements

Daemons.run_proc("scheduler", 
                 :log_output => true, 
                 :dir_mode => :normal, 
                 :dir => "#{RAILS_ROOT}/log") do
  begin
    require File.join(RAILS_ROOT, "config/environment")
 
    puts "starting scheduler at #{Time.now} for #{RAILS_ENV}"
    SchedulerDaemon.new.run
 
  ensure
    puts "ending scheduler at #{Time.now}"
  end
end

This was actually pretty easy, and next time it will take 5 minutes to create a daemon. Nice gem.

Tags: ,

Comments are closed.