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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With