2015-10-15 6 views
12

Von der Rails-API, fand ich ActiveJob Intervall retry_job kann:Wie wird die Anzahl der Wiederholungen für Sidekiq mit ActiveJob festgelegt?

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

Aber wenn ich will gesetzt Wiederholungsanzahl, wie Sidekiq suchen:

include Sidekiq::Worker 
sidekiq_options :retry => 5 

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

Wie in diesem Beispielcode?

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

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

Jetzt habe ich das meine Job-Klasse:

Sidekiq.default_worker_options = { retry: 5 } 

Aber es scheint nicht sehr gut.

Antwort

2

Siehe here die Standardeinstellungen für Sidekiq. Das Attribut retry "akzeptiert" einen booleschen Wert und keine Zahl, wie Sie angenommen haben.

Von der Zusammenführung von active_job in Rails diese other file kann man sehen, dass wieder retry die Anzahl der Wiederholungen nicht akzeptiert.

Was ist die documentation says dann ist, dass pro Job können Sie definieren, ob der Job erneut versucht oder nicht.

Ich habe auch versucht zu finden, ob die config/sidekiq.yml Datei diese Nummer erhalten kann, und es scheint, als ob es nicht kann.

Schließlich

Wenn Sie den Fehler innerhalb von 25 Wiederholungen nicht beheben (etwa 21 Tage), wird Sidekiq erneuten Versuch stoppen und Ihre Arbeit in die Queue Toten Job bewegen. Sie können den Fehler beheben und den Auftrag innerhalb der nächsten 6 Monate mithilfe der Webbenutzerschnittstelle manuell erneut versuchen.

+0

Sie sind falsch. 'Wiederholen' kann eine Nummer sein. https://github.com/mperham/sidekiq/wiki/Error-Handling#configuration –

+1

Der Titel Ihrer Frage sagt "mit ActiveJob". Die von Ihnen gesendete URL stammt nicht von ActiveJob. Der Besitzer des Repos (@MikePerham) antwortete ebenfalls und sagte, Sie können nicht –

+0

Danke. Ich habe 'Sidekiq.default_worker_options = {retry: 5}' in meine Klasse eingefügt. Aber scheint Arbeit schlechter (wiederholen Sie oft an einem Tag!). Die Standardwiederholung Zeiten ist 25. Dann kann ich es nicht anpassen? – scho

8

Sie können nicht. Wenn Sie Sidekiq-spezifische Funktionen verwenden möchten, müssen Sie Sidekiq-spezifische APIs verwenden. ActiveJob legt den Wiederholungsmechanismus von Sidekiq nicht offen.

+0

Vielen Dank. Was ist 'Sidekiq-spezifisch'? Können Sie mir sagen, wie man es in der ActiveJob-Klasse verwendet? – scho

+1

Die Methode 'sidekiq_options' für einen! –

+0

Vielen Dank. – scho

0

wenn Sie nur sidekiq verwenden, nerver Änderung Backend kann Affe Patch helfen Ihnen

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 

dann, Sie wie unten schreiben:

class BaseJob < ActiveJob::Base 

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

    def perform; end 
end 

glücklich Codierung

12

Das könnte dir auch Interesse an dieser Lösung, die serialize und deserialize API verwendet, um die Anzahl der Versuche zu speichern.

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 

Nehmen Sie es von here.

1

Es ist ein sidekiq-retry Juwel, das die Arbeit erledigt

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

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

Eine weitere Option ist das sidekiq middleware:

Zuerst definieren job_options Klasse-Methode, die in den Unterklassen zur Verfügung stehen wird:

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

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

Add Middleware, die Jo liest b_options aus der Klasse der Arbeitsplätze und schreibt sie in den Arbeitsposten für 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 

Und schließlich

class SiteScrapperJob < ApplicationJob 
    job_options retry: 5 

    def perform 
    # your code 
    end 
end 
1

Da Rails 5.1, gibt es eine eingebaute Möglichkeit, dies mit der retry_on Methode zu tun. Es ist eine allgemeine ActiveJob-Methode, so dass es mit jedem Warteschlangen-Backend arbeiten kann, nicht nur Sidekiq.

Zum Beispiel für Ihren spezifischen Job könnten Sie tun:

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

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

Sie können auch ein konstantes Warteintervall oder eine exponentielle Warte Strategie, wie sie in den docs erläuterten.

Verwandte Themen