Search code examples
ruby-on-railsrubydelayed-job

Why doesn't delayed job load my serialized arguments from the DB?


When I schedule my delayed job, I do it in the usual way:

NotificationMailer.delay.notify(self, @current_user)

And if I peek at the object on the Delayed::Job queue (before the worker sees it), I can see my serialized parameter current_user in the handler:

[33] my_project »  Delayed::Job.first
  Delayed::Backend::ActiveRecord::Job Load (0.7ms)  SELECT "delayed_jobs".* FROM "delayed_jobs" ORDER BY "delayed_jobs"."id" ASC LIMIT 1
=> #<Delayed::Backend::ActiveRecord::Job:0x0000010d546fb0> {
          :id => 764161,
    :priority => 0,
    :attempts => 0,
     :handler => "--- !ruby/object:Delayed::PerformableMailer\nobject: !ruby/class 'SurveyCompletionNotificationMailer'\nmethod_name: :notify\nargs:\n- !ruby/ActiveRecord:MyInstance\n  attributes:\n    id: 10786\n   created_at: 2013-12-19 03:52:21.082910000 Z\n    updated_at: 2014-07-23 19:12:27.967755000 Z\n  delta: true\n- !ruby/ActiveRecord:User\n  attributes:\n    id: 30\n    first_name: Andrew\n    last_name: Anderson\n    created_at: 2013-01-16 16:40:20.980147000 Z\n    updated_at: 2013-01-16 16:40:20.980147000 Z\n    title: Compensation Analyst\n    primary_phone_number: '123456789'\n    supervisor_id: \n    status: modified\n    disabled: \n    prefix: \n    suffix: ''\n    department: ''\n    general_info: ''\n    contact_id: 4428\n    emulating: true\n",
  :last_error => nil,
      :run_at => Wed, 23 Jul 2014 14:12:27 CDT -05:00,
   :locked_at => nil,
   :failed_at => nil,
   :locked_by => nil,
       :queue => nil,
  :created_at => Wed, 23 Jul 2014 14:12:27 CDT -05:00,
  :updated_at => Wed, 23 Jul 2014 14:12:27 CDT -05:00
}

But I find that Delayed Job will ignore the serialized argument data and reload the User record from the database. So if the User record changes between when the job is queued and when it executes, the new data will be used. This is not what I want. Why even bother the serialize the parameters if you're not going to use it? Am I missing something? Any way to get DJ to use the serialized argument data?


Solution

  • This is the behavior of DJ, it just uses the deserialized id to load the ActiveRecord object from DB (here is a related FAQ entry). If you want it to do something different, you would either need to monkeypatch ActiveRecord, or to pass the attributes as additional parameters to the mailer.