Delayed::Job.enqueue queuing up jobs, and Heroku clearing them from the queue, but my perform method is never called; why?
I am enqueuing jobs in my Rakefile's cron task, as such:
Delayed::Job.enqueue(MyJob.new(variable))
I have a class in /lib as follows:
class MyJob < Struct.new(:variable)
def perform
Watchdog.create(:module => 'MyJob', :messagetype => 'Notice', :message => "Variable is #{variable}")
end
end
I have a Watchdog class, as follows:
class Watchdog < ActiveRecord::Base
attr_accessible :id,
:module,
:message_type,
:message,
:created_at,
:updated_at
end
I have deployed this to Heroku.开发者_如何学C After I run heroku rake cron, I see a job gets placed in my Delayed_jobs table (e.g., it is enqueued), and I see that after I add a worker, it is removed from the queue. However a call to Watchdog.all returns an empty set.
Therefore, it appears that the job is enqueued and dequeued, but that the perform method of my MyJob object is not executed.
I am running Rails 3 and Ruby 1.8.7 on Heroku.
Does anyone know why my perform method isn't being called? Thanks very much for your help. I'm relatively new to Rails.
The way I write my DelayedJob classes would be in this format:
class MyJob
attr_accessor :variable
def initialize(variable)
self.variable = variable
end
def perform
Watchdog.create(:module => 'MyJob', :messagetype => 'Notice', :message => "Variable is #{variable}")
end
end
This may be functionally equivalent to what you are doing, but I know this form works.
As it turned out, with very much respect to both of those who offered possible solutions to this problem, neither was on the mark. Upon much further investigation, what I determined is that my MyJob class was not available to the job:work rake task when it ran on Heroku (or on my local machine for that matter). What I did to solve this was to include in my config/application.rb file the line:
require './lib/my_job.rb'
Then, when Delayed::Job dequeued the job and YAML::load()ed the handler, the class definition was available to it, it was able to create the new object and run the perform method on it.
I bet that it's not delayed job at all. Maybe the code itself is failing, not the job enqueue/dequeue. Try checking heroku logs
and see if it's failing for some reason.
Also, are you positive that MyJob.perform works as expected? You can use heroku console
to start an interactive ruby shell directly on Heroku. Try initializing a MyJob
class and running perform
to make sure it works.
Possibility 1
Class Watchdog
has attribute message_type
, but your job creates a Watchdog
with an attribute messagetype
.
Possibility 2
DelayedJob may not be able to serialize and deserialize a job class inheriting from Struct.new(:variable)
.
Try the approach that Steve Wilhelm suggested and just use a "normal" class definition:
class MyJob
attr_accessor :variable
initialize(variable)
self.variable = variable
end
def perform
Watchdog.create(
:module => 'MyJob',
:message_type => 'Notice',
:message => "Variable is #{variable}"
)
end
end
精彩评论