Home > Ruby On Rails > Delayed_job for background processing in Rails

Delayed_job for background processing in Rails

The first thing to do obviously is to install DelayedJob. There are plenty of forked versions available on git-hub. I chose collectiveidea beacuse it was recommend on railscasts. I did refer to this site extensively for setting up delayed_job.

$ sudo gem install collectiveidea-delayed_job

Job half done. I followed instructions on the github page and ensure that I have my environment setup properly. I added the following to the environment.rb:

 config.gem 'collectiveidea-delayed_job', :lib => 'delayed_job',
                     :source => 'http://gems.github.com'

and the following to the Rakefile:

begin
      require 'delayed/tasks'
rescue LoadError
      STDERR.puts "Run `rake gems:install` to install delayed_job"
end

Then issue the command:

./script/generate delayed_job
rake db:migrate

To start the delayed_job server in production mode, issue:

$ RAILS_ENV=production ./script/delayed_job start

To start it in development mode, issue:

$ rake jobs:work

Interesting find – obvious but cost me a lot of time: Nothing stops one from running BOTH the above commands. Infact, in production mode I ran the delayed_job as a daemon AND also using rake. Silly me – I forgot that if I change any code I would need to restart both. I wrongly assumed that jobs:work only ‘showed’ the console — it starts the delayed_job server. So, if you do it this way, you will have twice the number of background jobs floating around ;)

Well, anyway, once I had this properly configured as a daemon, I set about changing code. This was the really aweome part of DelayedJob — no dependencies!! I changed the code from:

user = User.find_by_name('xyz')
user.get_daily_call_statistics

to

user = User.find_by_name('xyz')
user.send_later(:get_daily_call_statistics)

AND IT WORKS !! Awesome.  While digging around a little more, I realized the there is not enough scope for debugging in the default way. I looked up github and google for some help and found this useful tip:

1. Create a config/initializers/delayed_job_config.rb and add:

Delayed::Job.destroy_failed_jobs = false
Delayed::Worker.logger = Rails.logger

This logs all delayed job output to the environment log files and ensures that failed jobs are not destroyed. There are other settings to reduce the failure attempts and the time for the delayed job but I was too excited to try them out immediately.

2. Suppose I have some global variables in the helpers, the are not accessible in the model methods called via delayed_job. Maybe a bug in delayed_job – I do plan to dig deeper into this and figure this one out — either way. I had to break my head trying to figure this one out.

To conclude, what I had earlier was:

Processing DashboardController#explicit_refresh_daily_statistics (for 121.247.65.47 at 2009-10-29 13:16:33) [GET]
Parameters: {"action"=>"explicit_refresh_daily_statistics", "controller"=>"dashboard"}
last seen ...........
Redirected to http://acemoney.in/dashboard
Completed in 74414ms (DB: 16912) | 302 Found [http://acemoney.in/dashboard/explicit_refresh_daily_statistics]

Now after adding the send_later, I have:

Processing DashboardController#explicit_refresh_daily_statistics (for 121.247.65.47 at 2009-10-29 15:16:41) [GET]
Parameters: {"action"=>"explicit_refresh_daily_statistics", "controller"=>"dashboard"}
last seen ...........
Redirected to http://acemoney.in/dashboard
Completed in 420ms (DB: 99) | 302 Found [http://acemoney.in/dashboard/explicit_refresh_daily_statistics]

This means my response time fell from from 74 seconds to 0.5 seconds

Now, I already had backgrounDrb tasks configured earlier and want to migrate them ‘somehow’ to DelayedJob with minimal code. Stay tuned, this post will be updated.

  1. November 4, 2009 at 9:59 am | #1

    I have added a new post for Moving from backgrounDrb to DelayedJob

  2. Sachin
    January 21, 2011 at 3:35 pm | #2

    Hi, I am trying to implement delayed job using mongoid, i have done a simple code for that. When i run rake jobs:work,i can see “1 jobs processed at 94.3685 j/s, 0 failed …” BUT when i check the database, it shows

    “{Job failed to load: uninitialized constant FirstJob. Handler: \”— !ruby/struct:FirstJob \\nmailing_id: 12\\n\”\u000a/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/backend/base.rb:81:in `rescue in payload_object’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/backend/base.rb:79:in `payload_object’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/backend/base.rb:87:in `invoke_job’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:120:in `block (2 levels) in run’\\n/usr/local/ruby/lib/ruby/1.9.1/timeout.rb:57:in `timeout’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:120:in `block in run’\\n/usr/local/ruby/lib/ruby/1.9.1/benchmark.rb:309:in `realtime’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:119:in `run’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:177:in `reserve_and_run_one_job’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:104:in `block in work_off’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:103:in `times’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:103:in `work_off’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:78:in `block (2 levels) in start’\\n/usr/local/ruby/lib/ruby/1.9.1/benchmark.rb:309:in `realtime’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:77:in `block in start’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:74:in `loop’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/worker.rb:74:in `start’\\n/home/sachin/.bundler/ruby/1.9.1/delayed_job-6c11015334aa/lib/delayed/tasks.rb:9:in `block (2 levels) in ‘\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:634:in `call’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:634:in `block in execute’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:629:in `each’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:629:in `execute’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:595:in `block in invoke_with_call_chain’\\n/usr/local/ruby/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:588:in `invoke_with_call_chain’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:581:in `invoke’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:2041:in `invoke_task’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:2019:in `block (2 levels) in top_level’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:2019:in `each’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:2019:in `block in top_level’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:2058:in `standard_exception_handling’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:2013:in `top_level’\\n/usr/local/ruby/lib/ruby/1.9.1/rake.rb:1992:in `run’\\n/usr/local/ruby/bin/rake:31:in `’”

    Not able to figure what is going where ?

  3. January 21, 2011 at 3:53 pm | #3

    1 job processed, 0 failed — this could the error for an older delayed job.

    rake jobs:clear
    rake jobs:work

    then try this. It should work.

    PS: I have discontinued my blog here — user http://blog.joshsoftware.com instead.
    Cheers!

  1. November 4, 2009 at 9:56 am | #1
  2. April 16, 2010 at 2:11 pm | #2
  3. December 7, 2011 at 1:57 am | #3

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.