nesquena / backburner

Simple and reliable beanstalkd job queue for ruby
http://nesquena.github.com/backburner
MIT License
428 stars 68 forks source link

Enqueuing a job with options doesn't work #115

Closed kaikousa closed 8 years ago

kaikousa commented 8 years ago

I'm trying to implement a delayed job that would wait 30 seconds before running.

args = [ version.id ]
opts = { :delay => 30 }
Backburner.enqueue(TerminateVersionJob, args, opts)

The job is as follows

require "backburner"

class TerminateVersionJob
  include Backburner::Queue

  queue "version-termination-jobs"
  queue_respond_timeout 600

  def self.perform(version_id)
    # redacted
  end

end

I run the worker queues like this:

bundle exec backburner -q version-termination-jobs -r lib/app.rb

When the worker picks up the job and tries to run it I get the following exception:

Work job TerminateVersionJob with [23, {"delay"=>30}]
Exception ArgumentError -> wrong number of arguments (2 for 1)
   lib/app/jobs/terminate_version_job.rb:11:in `perform'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/job.rb:54:in `block (2 levels) in process'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/job.rb:94:in `block in timeout_job_after'
   /usr/lib/ruby/2.2.0/timeout.rb:88:in `block in timeout'
   /usr/lib/ruby/2.2.0/timeout.rb:32:in `block in catch'
   /usr/lib/ruby/2.2.0/timeout.rb:32:in `catch'
   /usr/lib/ruby/2.2.0/timeout.rb:32:in `catch'
   /usr/lib/ruby/2.2.0/timeout.rb:103:in `timeout'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/job.rb:94:in `timeout_job_after'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/job.rb:54:in `block in process'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/hooks.rb:28:in `call'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/hooks.rb:28:in `block in around_hook_events'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/hooks.rb:37:in `call'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/hooks.rb:37:in `around_hook_events'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/job.rb:48:in `process'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/worker.rb:135:in `work_one_job'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/workers/simple.rb:25:in `block in start'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/workers/simple.rb:25:in `loop'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/workers/simple.rb:25:in `start'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/worker.rb:58:in `start'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner.rb:39:in `work'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/cli.rb:23:in `block in start'
   /var/lib/gems/2.2.0/gems/dante-0.2.0/lib/dante/runner.rb:123:in `call'
   /var/lib/gems/2.2.0/gems/dante-0.2.0/lib/dante/runner.rb:123:in `start'
   /var/lib/gems/2.2.0/gems/dante-0.2.0/lib/dante/runner.rb:74:in `execute'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/lib/backburner/cli.rb:20:in `start'
   /var/lib/gems/2.2.0/gems/backburner-1.2.0/bin/backburner:7:in `<top (required)>'
   /usr/local/bin/backburner:23:in `load'
   /usr/local/bin/backburner:23:in `<main>'
Finished TerminateVersionJob in 12ms failed: attempt 1 of 1, burying

I tried reading the source code and to me it seems that there is something funky going on with how the arguments are handled and passed down to jobs as the job seems to get the options as well. Maybe a mistake with user of multiple arguments (*args), but I'm not completely sure.

I hacked my way around this by changing the job perform-method to:

def self.perform(version_id, options={})

This saves the day but I would like to see a solution for the problem (or to know if I'm doing something wrong) as now the program doesn't work when passing options like it is documented. I can also look into it and hopefully contribute with PR if I get some pointers about where to look for.

kaikousa commented 8 years ago

Actually it seems that my "workaround" only makes the code run, the job is not delayed at all so the options are ignored.

nesquena commented 8 years ago

Try Backburner::Worker.enqueue(NewsletterJob, ['foo@admin.com', 'lorem ipsum...'], :delay => 1.hour) Note the use of Backburner::Worker

kaikousa commented 8 years ago

I was blind like a bat! :D Thanks @nesquena !!