Available for hire
How to Integrate Delayed Job Into Your App

So a quick how to integrate delayed job into your app, since i’ve found a lot of the tutorials out there leave out some crucial information. Firstly, I used Tobi’s delayed_job since it comes with a few extra bits a pieces, like generators and the like. Install the plugin You can either install it using the rails command, or use git submodules (which i won’t cover here)

script/plugin install git://github.com/tobi/delayed_job.git

Generate and run the migration We’ll run the generator script to generate our migration and then migrate the database up

script/generate delayed_job_migration

Which will generate a migration that looks like this. Have a read through the file. You’re probably asking yourself where the object to be run is stored. Its actually stored in the “handler” field as a sexy yaml field.

  create_table :delayed_jobs, :force => true do |table|
    table.integer  :priority, :default => 0      # Allows some jobs to jump to the front of the queue
    table.integer  :attempts, :default => 0      # Provides for retries, but still fail eventually.
    table.text     :handler                      # YAML-encoded string of the object that will do work
    table.string   :last_error                   # reason for last failure (See Note below)
    table.datetime :run_at                       # When to run. Could be Time.now for immediately, or sometime in the future.
    table.datetime :locked_at                    # Set when a client is working on this object
    table.datetime :failed_at                    # Set when all retries have failed (actually, by default, the record is deleted instead)
    table.string   :locked_by                    # Who is working on this object (if locked)
    table.timestamps
  end

How to queue mail in your app Lets say for example we have a AccountsMailer

class AccountMailer < ActionMailer::Base  
  def confirm(user)
    subject       'Your account has been created'
    recipients    user.email
    from          'you@email.com'
    sent_on       Time.zone.now
    content_type  'text/html'
    body "Welcome Aboard"
  end
end

We would normally send an email by doing something like this in our controllers

AccountMailer.deliver_confirm(@user)

With delayed job, we can simply do a

AccountMailer.send_later(:deliver_confirm,@user)

So delayed job adds a send_later class method, which takes an AccountMailer class method as its first param, and then the methods params as the next. How to send the mail Setting up actionmailer is outside of the scope of this post. So i’m assuming you have it set up already. The jobs at this stage are being queued in your database, but we haven’t started any sort of job to process the queue. To start the queue simple run

rake jobs:work

You should see the queue starting to process, or at idle if its empty. This is great, but what happens if the rake task dies for some reason???? Daemons to rescue!!! Daemonising delayed job queue processor First install the daemons gem

sudo gem install daemons

Next create a script in your script/ directory.. I called mine delayed_job

#!/usr/bin/env ruby
require 'rubygems'
require 'daemons'
dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))

daemon_options = {
  :multiple   => false,
  :dir_mode   => :normal,
  :dir        => File.join(dir, 'tmp', 'pids'),
  :backtrace  => true
}

Daemons.run_proc('job_runner', daemon_options) do
  if ARGV.include?('--')
    ARGV.slice! 0..ARGV.index('--')
  else
    ARGV.clear
  end

  Dir.chdir dir
  RAILS_ENV = ARGV.first || ENV['RAILS_ENV'] || 'development'
  require File.join('config', 'environment')

  Delayed::Worker.new.start
end

Save that, and you can now simple do the below to start the queue.

script/delayed_job start

I would recommend reading up on the delayed_job and daemons extensions to understand the inner workings, but at least this is enough to get you up and running! notes You can also clear the queue by running

rake jobs:clear