process snippets

How to create a daemon process using Ruby and the daemons RubyGem

Tagged ruby, daemon, daemons, process, background  Languages ruby

This snippets shows you how to create a daemon process out of an ordinary Ruby script.

First you'll need the daemons gem:

gem install daemons

Then you'll need the daemon script, for example daemon.rb:

require 'rubygems'
require 'daemons'

pwd  = File.dirname(File.expand_path(__FILE__))
file = pwd + '/../lib/background_service.rb'

Daemons.run_proc(
  'background_service', # name of daemon
#  :dir_mode => :normal
#  :dir => File.join(pwd, 'tmp/pids'), # directory where pid file will be stored
#  :backtrace => true,
#  :monitor => true,
  :log_output => true
) do
  exec "ruby #{file}"
end

Change the file variable to point to the script you want to daemonize and your good to go.

You can now execute the daemon.rb script without parameters to get a list of available commands for controlling the daemon process:

ERROR: no command given

Usage: lib/background_service.rb <command> <options> -- <application options>

* where <command> is one of:
  start         start an instance of the application
  stop          stop all instances of the application
  restart       stop all instances and restart them afterwards
  run           start the application and stay on top
  zap           set the application to a stopped state

* and where <options> may contain several of the following:

    -t, --ontop                      Stay on top (does not daemonize)
    -f, --force                      Force operation

Common options:
    -h, --help                       Show this message
        --version                    Show version

How to get monit to start mongrel_rails properly

Tagged process, monit, monitoring, mongrel_rails  Languages bash

Mongrel_rails and monit are not the best of friends. It's difficult to get them to work together.

For example, this is the error I got in my monit logs when switching to a new mongrel_rails command that cleans up stale pids:

'mongrel_1' process is not running
'mongrel_2' trying to restart
'mongrel_3' start: /usr/local/bin/mongrel_rails
'mongrel_4' failed to start

To fix it I added the following start_command to the monit configuration:

/usr/bin/env PATH=/usr/local/bin/:$PATH mongrel_rails cluster::start -C /var/www.... --clean --only 8000

The problem is that monit overrides the PATH environment variable, so it won't find mongrel_rails unless you tell it where to find it. Monit also contains a bug which doesn't tell you why it can't start mongrel_rails, but that's another story...

Note that I'm using the --clean switch which will startup the mongrels even if a stale pid exists.

In fact I got so tired of the whole mess I wrote a plugin that generates a working monit configuration for mongrel_rails from one or more mongrel_cluster.yml configuration files.