Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delayed_job not executing the perform method but emptying the job queue

I have a fresh rails 3 app, here's my Gemfile:

source 'http://rubygems.org'
gem 'rails', '3.0.0' gem 'delayed_job'
gem 'sqlite3-ruby', :require => 'sqlite3'

Here's the class that represents the job that I want to queue:

class Me < Struct.new(:something)
   def perform
     puts "Hello from me"
     logger.info "Hello from me"
     logger.debug "Hello from me"
     raise Exception.new   
   end
end

From the console with no workers running:

irb(main):002:0> Delayed::Job.enqueue Me.new(1)
=> #<Delayed::Backend::ActiveRecord::Job id: 7, priority: 0, attempts: 0, handler: "--- !ruby/struct:Me \nsomething: 1\n", last_error: nil, run_at: "2010-12-29 07:24:11", locked_at: nil, failed_at: nil, locked_by: nil, created_at: "2010-12-29 07:24:11", updated_at: "2010-12-29 07:24:11">

Like I mentioned: there are no workers running:

irb(main):003:0> Delayed::Job.all
=> [#<Delayed::Backend::ActiveRecord::Job id: 7, priority: 0, attempts: 0, handler: "--- !ruby/struct:Me \nsomething: 1\n", last_error: nil, run_at: "2010-12-29 07:24:11", locked_at: nil, failed_at: nil, locked_by: nil, created_at: "2010-12-29 07:24:11", updated_at: "2010-12-29 07:24:11">]

I start a worker with script/delayed_job run

The queue gets emptied:

irb(main):006:0> Delayed::Job.all
=> []

However, nothing happens as a result of the puts, nothing is logged from the logger calls, and no exception is raised. I'd appreciate any help / insight or anything to try.

like image 512
James Avatar asked Dec 29 '10 07:12

James


1 Answers

By default, delayed_job destroys failed jobs:

So the first step is to configure an initializer and deactivate that behaviour

Delayed::Worker.destroy_failed_jobs = false  

Also, if you get a deserialization failure, then that is an instant job failure.

This triggers job deletion (if you haven't deleted it).

So try adding the following around line 120 of the worker.rb

rescue DeserializationError => error
  say "DeserializationError: #{error.message}"
  job.last_error = "{#{error.message}\n#{error.backtrace.join('\n')}"
  failed(job)

It's fairly unhelpful, but at least you'll know it's a deserialization error then.

I ended up just using the job w. perform() method construct. Much more reliable. Also remember to put your job definition as a separate file so the class loader can find it when it is running (rather than just inlining the class definition into your model somewhere).

like image 171
Ben Walding Avatar answered Oct 03 '22 06:10

Ben Walding