在所有延迟工作之前挂钩

时间:2011-08-23 19:23:14

标签: ruby-on-rails ruby delayed-job

是否可以在ALL delayed_job任务之前运行方法?

基本上,我们正在尝试确保运行delayed_job的每个服务器都有我们代码的最新实例,因此我们希望运行一个方法,在每个作业运行之前对其进行检查。

(我们已经有了“检查”方法并在其他地方使用它。问题只是关于如何从delayed_job调用它。)

2 个答案:

答案 0 :(得分:10)

现在有一种官方方法可以通过插件来实现。此博客文章清楚地描述了如何执行此操作,使用示例http://www.salsify.com/blog/delayed-jobs-callbacks-and-hooks-in-rails(本文中描述的某些事件可能已过时。请参阅下面的基于已更新的DJ源的更新列表)

基本上,您实现了一个初始化程序,它设置了如下所示的delayed_job插件:

# config/initializers/delayed_job_my_delayed_job_plugin.rb

module Delayed
  module Plugins
    class MyDelayedJobPlugin < Plugin
      callbacks do |lifecycle|
        # see below for list of lifecycle events
        lifecycle.after(:invoke_job) do |job|
          # do something here
        end
      end
    end
  end
end

Delayed::Worker.plugins << Delayed::Plugins::MyDelayedJobPlugin

您将可以访问以下生命周期事件和适用的参数:

  :enqueue    => [:job],
  :execute    => [:worker],
  :loop       => [:worker],
  :perform    => [:worker, :job],
  :error      => [:worker, :job],
  :failure    => [:worker, :job],
  :invoke_job => [:job]

答案 1 :(得分:0)

你可以使用一个邪恶的双胞胎,根据定义,这是一个黑客,但应该工作。请参阅我在代码中添加的注释,以获得有关您需要进行调整的一些解释。

vendor/plugins/delayed_job_hacks/init.rb

Delayed::Backend::ActiveRecord::Job.class_eval do
  def self.foo
    puts "I'm about to enqueue your job. Maybe throw an exception. Who knows!?"
  end

  def self.enqueue(*args, &block)
    object = block_given? ? EvaledJob.new(&block) : args.shift

    # Do your checking or whatever here.
    foo

    unless object.respond_to?(:perform) || block_given?
      raise ArgumentError, 'Cannot enqueue items which do not respond to perform'
    end

    priority = args.first || 0
    run_at = args[1]

    # Notice that this is now "Delayed::Job" instead of "Job", because otherwise
    # Rails will try to call "Rails::Plugin::Job.create" and you'll get explosions.
    Delayed::Job.create(:payload_object => object, :priority => priority.to_i, :run_at => run_at)
  end
end