2015-10-15 78 views
12

從Rails的API,我發現ActiveJob可以retry_job間隔:如何使用ActiveJob設置Sidekiq的重試次數?

my_job_instance.enqueue 
my_job_instance.enqueue wait: 5.minutes 
my_job_instance.enqueue queue: :important 
my_job_instance.enqueue wait_until: Date.tomorrow.midnight 

http://api.rubyonrails.org/classes/ActiveJob/Enqueuing.html

但如果我想設置重試次數,如Sidekiq的:

include Sidekiq::Worker 
sidekiq_options :retry => 5 

https://github.com/mperham/sidekiq/wiki/Error-Handling

如何在這個示例代碼?

class SiteScrapperJob < ActiveJob::Base 
    rescue_from(ErrorLoadingSite) do 
    retry_job queue: :low_priority 
    end 

    def perform(*args) 
    # raise ErrorLoadingSite if cannot scrape 
    end 
end 

現在,我已將此添加到我的作業類:

Sidekiq.default_worker_options = { retry: 5 } 

但似乎不是很好。

回答

2

請參閱here Sidekiq的默認設置。如您所設想的,屬性retry「接受」布爾值而不是數字。

從active_job合併到Rails other file可以看出,再次retry不接受重試次數。

那麼documentation says的作用就是每個作業可以定義的作業是否重試。

我也試圖找到config/sidekiq.yml文件是否可以接收這個數字,而且看起來好像不能。

最後,

如果不解決25重(約21天)內的bug,Sidekiq將停止重試和移動作業到死作業隊列。您可以在未來6個月內隨時使用Web UI手動修復該錯誤並重試該作業。

+0

你錯了。 '重試'可以是一個數字。 https://github.com/mperham/sidekiq/wiki/Error-Handling#configuration –

+1

你的問題的標題說「與ActiveJob」。您發送的網址不是來自ActiveJob。回購所有人(@MikePerham)回覆說,你不能 –

+0

謝謝。我已將'Sidekiq.default_worker_options = {retry:5}'添加到我的課程中。但似乎工作更糟糕(有一天重試很多次!)。默認的重試次數是25.那麼我不能自定義它嗎? – scho

8

你不能。如果你想使用Sidekiq特定的東西,你需要使用Sidekiq特定的API。 ActiveJob不公開Sidekiq的重試機制。

+0

內拯救了異常。謝謝。什麼是'Sidekiq特定'?你能告訴我如何在ActiveJob類中使用它嗎? – scho

+1

一個方法'sidekiq_options'! –

+0

非常感謝。 – scho

0

,如果你只是用sidekiq,nerver改變後端,猴子補丁可以幫助你

module ActiveJob 
    module QueueAdapters 
    class SidekiqAdapter 
     def enqueue(job) 
     JobWrapper.sidekiq_options job.sidekiq_options_hash if job.sidekiq_options_hash 
     JobWrapper.sidekiq_retry_in job.sidekiq_retry_in_block if job.sidekiq_retry_in_block 
     Sidekiq::Client.push(
      'class' => JobWrapper, 
      'wrapped' => job.class.to_s, 
      'queue' => job.queue_name, 
      'args' => [ job.serialize ] 
     ) 
     end 

     def enqueue_at(job, timestamp) 
     JobWrapper.sidekiq_options job.sidekiq_options_hash if job.sidekiq_options_hash 
     JobWrapper.sidekiq_retry_in job.sidekiq_retry_in_block if job.sidekiq_retry_in_block 
     Sidekiq::Client.push(
      'class' => JobWrapper, 
      'wrapped' => job.class.to_s, 
      'queue' => job.queue_name, 
      'args' => [ job.serialize ], 
      'at' => timestamp 
     ) 
     end 
    end 
    end 

    class Base 
    class_attribute :sidekiq_options_hash 
    class_attribute :sidekiq_retry_in_block 

    def self.sidekiq_options(opts={}) 
     self.sidekiq_options_hash = opts 
    end 

    def self.sidekiq_retry_in(&block) 
     self.sidekiq_retry_in_block = block 
    end 
    end 
end 

然後,你可以象下面這樣寫:

class BaseJob < ActiveJob::Base 

    sidekiq_options retry: 2, queue: :low 
    sidekiq_retry_in { |count, _| 3 * count } 

    def perform; end 
end 

編碼快樂

12

您也可能對此解決方案感興趣,它使用serializedeserialize api來存儲嘗試次數。

class DeliverWebhookJob < ActiveJob::Base 
    def serialize 
    super.merge('attempt_number' => (@attempt_number || 0) + 1) 
    end 

    def deserialize(job_data) 
    super 
    @attempt_number = job_data['attempt_number'] 
    end 

    rescue_from(ErrorLoadingSite) do |exception| 
    retry_job(wait: 10) if @attempt_number < 5 
    end 

    def perform(*args) 
    # raise ErrorLoadingSite if cannot scrape 
    end 
end 

把它從here

1

有一個sidekiq-retry寶石其做工作

class SiteScrapperJob < ActiveJob::Base 
    include ActiveJob::Retry.new(limit: 5, strategy: :exponential) 

    def perform(*args) 
    # raise ErrorLoadingSite if cannot scrape 
    end 
end 

另一種選擇是使用sidekiq middleware

首先定義job_options類的方法,該方法將在子類可用:

class ApplicationJob < ActiveJob::Base 
    def self.job_options(options) 
    @job_options = options 
    end 

    def self.get_job_options 
    @job_options || {} 
    end 
end 

添加讀取joe的中間件從喬布斯的類b_options,並將其寫入到作業項爲sidekiq:

module Sidekiq 
class JobOptionsMiddleware 

    def call(job_wrapper, item, queue, redis_pool) 
    job = item['args'][0]['job_class'].constantize 

    job.get_job_options 
     .each{ |option, value| item[option] = value if item[option].nil? } 

    yield 
    end 

end 

# in sidekiq initializer 

Sidekiq.configure_client do |config| 
    config.client_middleware do |chain| 
    chain.add Sidekiq::JobOptionsMiddleware 
    end 
end 

最後

class SiteScrapperJob < ApplicationJob 
    job_options retry: 5 

    def perform 
    # your code 
    end 
end 
1

因爲Rails的5.1,有一個內置的方式做到這一點使用retry_on方法。這是一個普通的ActiveJob方法,所以它可以用於任何排隊後端,而不僅僅是Sidekiq。

例如,對於您的具體工作,你可以這樣做:

class SiteScraperJob < ActiveJob::Base 
    retry_on ErrorLoadingSite, queue: :low_priority, attempts: 5 

    def perform(*args) 
    # raise ErrorLoadingSite if cannot scrape 
    end 
end 

您還可以設置一個恆定的等待區間或指數的等待策略,如docs解釋。

相關問題