簡體   English   中英

將塊傳遞給delayed_job

[英]Passing a Block to a 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 

當我運行這個函數時,我傳入一個塊:

 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

這在沒有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 ...

它似乎沒有拿起傳入的塊。這不是正確的方法,或者我應該找到一個不同的方法?

delayed_job的工作原理是將作業保存到數據存儲(通常是主數據庫)中,然后在后台進程中將作業加載到此數據存儲中,並在其中處理/執行。

要將作業保存到數據庫中,delayed_job需要以某種方式保存使用什么參數調用哪個對象的方法。 這是通過將所有內容序列化為字符串來完成的(delayed_job使用yaml )。 不幸的是,塊無法序列化。 所以后台工作者不知道塊參數,並在沒有它的情況下調用該方法。 當方法試圖屈服於塊時,這會導致LocalJumpError

我找到了一種方法。 它有點hacky但效果很好。 我發現這篇文章討論了如何創建SerializableProc類。 如果我把它傳遞給函數,那么一切都很好。

大多數人會將此視為抽象問題。

proc代碼可能不會從run-to-run(vars除外)改變,所以你應該將塊代碼變成類或實例方法。 傳遞該方法的名稱,然后在execute方法中調用它,如

@some_data = CapJobs.send( target_method )

或許甚至更好

@some_data = DomainSpecificModel.send( target_method )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM