Skip to content
professor edited this page Sep 12, 2010 · 48 revisions

FAQ

Q: How do I set the priority of a job?

A: Jobs with a higher priority number will be run before other jobs. Normally, jobs are given a priority of 0. Here’s an example where we set the priority to “1”, which means it will run before any other jobs in the queue with a lower priority number:

Delayed::Job.enqueue(NewsletterJob.new('text', User.find(:all).collect(&:email)), 1)

Q: How do I set a job to start at a later (or specific time)?

A: One way is using send_at:

BatchImporter.new(Shop.find(1)).send_at(1.hour.from_now, :import_massive_csv, massive_csv)

Here’s an example that would set the job to run 5 minutes from now. The “0” is the default priority level for the job, the “5.minutes.from_now” sets the job to run 5 minutes from the time it’s saved in the delayed_jobs table:

Delayed::Job.enqueue(NewsletterJob.new('text', User.find(:all).collect(&:email)), 0, 5.minutes.from_now)

Q: Hello, tobi, I tried this plugin but I got 2 failing built-in specs. The “delayed_job / lib / delayed / job.rb” line 94 is “(`locked_at` IS NULL OR `locked_at` < #{quote_value(now + max_run_time)})”. Should it be “(… < #{quote_value(now – max_run_time)})”?

A: I got that same error. I think it’s a problem with postgres compatibility. It appears to be fixed with this commit. This is now fixed in master; dj should support all database adapters that ActiveRecord implements.

Q: How to a configure the plugin to save failed jobs?

A: Here’s how I configured the plugin. I also wanted to change the number of max attempts, etc:

  # config/initializers/delayed_job_config.rb
  Delayed::Job.destroy_failed_jobs = false
  silence_warnings do
    Delayed::Job.const_set("MAX_ATTEMPTS", 3)
    Delayed::Job.const_set("MAX_RUN_TIME", 5.minutes)
  end

Q: I’m having trouble keeping the job running going when jobs fail. Isn’t there a way to store the error message and move on?

A: My errors are long, so I had to change the last_error column from string to text:


class ChangeLastErrorInDelayedJobsToText < ActiveRecord::Migration
  def self.up
    change_column :delayed_jobs, :last_error, :text
  end

  def self.down
    change_column :delayed_jobs, :last_error, :string
  end
end

Q: Why do I get an error talking about Struct::Group if I use Group.find within a perform method?

A: There’s a strange edge-case with Ruby/Rails where Struct::Group already exists, so calling Group.anything from within a class that inherits from Struct will have strange results. You can workaround this issue by prefixing calls to Group with two colons. For example, ::Group.find would work as expected.

Q: Why am I getting a NoMethodError error that looks like this:

NoMethodError (undefined method `second' for #<Array:0x5588d10>):
    /vendor/plugins/delayed_job/lib/delayed/job.rb:87:in `enqueue'

A: The plugin is incompatible with Rails versions less than 2.2 since this commit in delayed_job, which relies on this commit in Rails. You can upgrade to Rails 2.2, or add a core extension to Array yourself like so:

# config/environment.rb
require 'lib/core_ext'

# lib/core_ext.rb
class Array
  def from(position)
    self[position..-1]
  end

  def to(position)
    self[0..position]
  end

  def second
    self[1]
  end

  def third
    self[2]
  end
end

Q: What can I do to prevent duplicate jobs from being queued up? Shouldn’t there be a check to see if the handler is the same for a job?

Q: Is DJ designed to work exclusively with rails?

A: Not necessarily. There is an example app with Sinatra. It is dependent on ActiveRecord, however. (Actually, as of 2.0, delayed_job supports a MongoMapper backend)

Q: I’m currently using a daemon to run a task every 30 seconds. Is DJ a good replacement for this?

Q: Can you provide an example of how to run the workers on a separate machine? I assume it should be the same rails project just deployed to a different machine, but maybe with a different environment so it connects to a remote server?

Q: Does each worker process run it’s own rails instance? Can you configure how often it polls the database?

Q: Can you show an example of how to save a job’s progress, so that it can resume from a failure in the middle and not duplicate work (I’m thinking for a newsletter here)?

<b<A: How about creating a job for each recipient of your newsletter. You get to see exactly who has received or not received your newsletter just by looking at the job queue. Also, you can ease the load on your mail server by scheduling the jobs to span a few hours if necessary.

Q. I sent a task to delayed job and it doesn’t seem to be working. How can I tell if it’s still in progress or whether there was an error that stopped it?

Q. How do I log or debug inside code that is running as a delayed job? For example, I’ve moved some code from a test method into a perform action, but it is no longer working. I’d like to see what is going wrong with a logger.debug.

A: If you create a job class such as “class PersonJob < Struct.new(id)” then PersonJob does not have access to the Rails Logger. You can access the Delayed Job logger with “Delayed::Worker.logger.debug()”