将块传递给delayed_job

Cha*_*ene 11 ruby ruby-on-rails block delayed-job

我有一个标记为由delayed_job异步处理的函数:

class CapJobs
  def execute(params, id)
    begin
      unless Rails.env == "test"
        Capistrano::CLI.parse(params).execute!
      end
    rescue
      site = Site.find(id)
      site.records.create!(:date => DateTime.now, :action => "Task Failure: #{params[0]}", :type => :failure)    
      site.save
    ensure
      yield id
    end 
  end   
  handle_asynchronously :execute
end 
Run Code Online (Sandbox Code Playgroud)

当我运行这个函数时,我传入一个块:

 capjobs = CapJobs.new
 capjobs.execute(parameters, @site.id) do |id|
   asite = Site.find(id)
   asite.records.create!(:date => DateTime.now, :action => "Created", :type => :init)
   asite.status = "On Demo"
   asite.dev = true
   asite.save
 end
Run Code Online (Sandbox Code Playgroud)

这在没有delayed_job的情况下运行时工作正常,但是当使用它运行时我得到以下错误

2012-08-13T09:24:36-0300: [Worker(delayed_job host:eagle pid:12089)] SitesHelper::CapJobs#execute_without_delay failed with LocalJumpError: no block given (yield) - 0 failed attempts
2012-08-13T09:24:36-0300: [Worker(delayed_job host:eagle pid:12089)] PERMANENTLY removing SitesHelper::CapJobs#execute_without_delay because of 1 consecutive failures.
2012-08-13T09:24:36-0300: [Worker(delayed_job host:eagle pid:12089)] 1 jobs processed at 0.0572 j/s, 1 failed ...
Run Code Online (Sandbox Code Playgroud)

它似乎没有拿起传入的块.这不是正确的方法,或者我应该找到一个不同的方法?

sev*_*rin 10

delayed_job的工作原理是将作业保存到数据存储(通常是主数据库)中,然后在后台进程中将作业加载到此数据存储中,然后处理/执行.

要将作业保存到数据库中,delayed_job需要以某种方式保存使用什么参数调用哪个对象的方法.这是通过将所有内容序列化为字符串来完成的(delayed_job使用yaml).不幸的是,块无法序列化.所以后台工作者不知道块参数,并在没有它的情况下调用该方法.这导致LocalJumpError该方法试图屈服于该块的时间.


Cha*_*ene 2

我找到了一种方法来做到这一点。这有点hacky但是效果很好。我发现这篇文章讨论了创建 SerializedProc 类。如果我将其传递给函数,那么一切都会很好。