Hook Before All Delayed Jobs

爱⌒轻易说出口 提交于 2019-12-10 14:39:25

问题


Is it possible to have a method run before ALL delayed_job tasks?

Basically, we're trying to make sure that every server that is running delayed_job has the latest instance of our code, so we want to run a method that checks this before every job is run.

(We already have the "check" method and use it elsewhere. The question is only about how to call it from delayed_job.)


回答1:


You could use an evil twin, which is by definition a hack, but should work. See the comments I added in the code for some explanation of tweaks you need to make.

In 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



回答2:


There is an official way to do this now, via plugins. This blog post clearly describes how to do this, with examples http://www.salsify.com/blog/delayed-jobs-callbacks-and-hooks-in-rails (some events described in this article maybe outdated. see below for updated list based on lated DJ sources)

Essentially, you implement an initializer that sets up a delayed_job plugin like below:

# 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

You will have access to the following lifecycle events, and applicable arguments:

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


来源:https://stackoverflow.com/questions/7166401/hook-before-all-delayed-jobs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!