在所有延迟作业之前挂钩

5

有没有可能在所有延迟的任务运行之前运行一个方法?

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

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

2个回答

11

现在有一种官方的方法可以通过插件来实现。这篇博客文章清楚地描述了如何做到这一点,并提供了示例http://www.salsify.com/blog/delayed-jobs-callbacks-and-hooks-in-rails(本文描述的某些事件可能已过时。请查看下面基于最新DJ源更新的列表)

基本上,您需要实现一个初始化程序,设置延迟作业插件,如下所示:

# 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]

哪个事件可以在作业成功执行后使用,更多细节我已经在这里添加了(http://stackoverflow.com/questions/41742169/hook-before-all-delyed-job-success-callback-to-save-successfully-completed-jobs)。 - Saurabh

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

这个能否适应在作业执行而非排队时工作? - Brian Glick
当然。看一下 job.rb 文件。我认为 run_with_lock 是一个不错的地方,甚至可以考虑 invoke_job,因为它非常简单,很容易制作出一个邪恶的副本。 - jdl
请将以下与编程有关的内容从英语翻译成中文。仅返回翻译后的文本:请参考我对这个问题的回答中官方的实现方式。 - Shyam Habarakada

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接