开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜