ActiveJobとSidekiqで自動再試行を無効にする方法はありますか?
Sidekiqだけで、
sidekiq_options :retry => false
ここで述べたように: https://github.com/mperham/sidekiq/wiki/Error-Handling#configuration
しかし、ActiveJobやSidekiqでは動作しないようです。
ここで提案されているように再試行を段階的に無効にする解決策も知っています: https://stackoverflow.com/a/28216822/2431728
しかし、それは私が必要とする行動ではありません。
回答ありがとうございます。
参考までに、私はActiveJob Githubリポジトリのこの主題に関連する問題でも質問しました: https://github.com/Rails/activejob/issues/47
DHHは私がテストしていないソリューションを私に答えましたが、それは仕事をすることができます。
個人的には、Sidekiqの再試行をグローバルに無効にするために、最終的にこれをイニシャライザに入れ、うまく機能します。
Sidekiq.configure_server do |config|
config.server_middleware do |chain|
chain.add Sidekiq::Middleware::Server::RetryJobs, :max_retries => 0
end
end
ActiveJobでSidekiqを構成する方法はありません。デフォルトを使用したくない場合は、Sidekiq Workerを使用します。
例外をキャッチして何もせずに再試行するか、再試行を構成できます。
class ExampleJob < ActiveJob::Base
rescue_from(StandardError) do |exception|
Rails.logger.error "[#{self.class.name}] Hey, something was wrong with you job #{exception.to_s}"
end
def perform
raise StandardError, "error_message"
end
end
class ExampleJob < ActiveJob::Base
rescue_from(StandardError) do |exception|
retry_job wait: 5.minutes, queue: :low_priority
end
def perform
raise StandardError, "error_message"
end
end
再試行を実行するには、retry_onメソッド retry_on method doc を使用できます
私もこれと同じニーズがありました。つまり、ActiveJobがSidekiqをラップしていますが、max_retriesをサポートしたいのです。これをイニシャライザに入れました。 #max_retriesがActiveJobジョブで定義されている場合、それは再試行の設定に使用されます。 #ephemeralの場合?が定義され、trueを返します。ジョブが再実行されず、失敗した場合、ジョブは「デッド」に転送されません。
class Foobar::SidekiqClientMiddleware
def call(worker_class, msg, queue, redis_pool)
aj_job = ActiveJob::Base.deserialize(msg['args'][0]) rescue nil
msg['retry'] = aj_job.respond_to?(:max_retries) ? aj_job.max_retries : 5
msg['retry'] = false if aj_job.respond_to?(:ephemeral?) && aj_job.ephemeral?
yield
end
end
Sidekiq.configure_client do |config|
config.redis = { url: "redis://#{redis_Host}:6379/12" }
config.client_middleware do |chain|
chain.add Foobar::SidekiqClientMiddleware
end
end
Sidekiq.configure_server do |config|
config.redis = { url: "redis://#{redis_Host}:6379/12" }
config.client_middleware do |chain|
chain.add Foobar::SidekiqClientMiddleware
end
end
注:実際にジョブの実行時に新しいジョブを作成する場合は、クライアントとサーバーの両方のミドルウェアチェーンにこれを追加することが実際に重要です。
sidekiq 6.0.1
以降、次のコードをActiveJobワーカーに渡して、再試行を防ぐことができます。
class ExampleJob < ActiveJob::Base
sidekiq_options retry: false
def perform(*args)
# Perform Job
end
end
詳細: https://github.com/mperham/sidekiq/wiki/Active-Job#customizing-error-handling
編集:
this によると、これにはRails 6.0.1
以降も必要です。
GemからのActiveJob
の再試行を無効にする(または他のSidekiqオプションを追加する)場合(ActionMailbox::RoutingJob
など)、このアプローチを使用できます(Rails 6.0.2+)。
1)必要なSidekiqオプションを使用してモジュールを作成します(ActiveSupport::Concern
を使用)
# lib/fixes/action_mailbox_routing_job_sidekiq_fix.rb
module ActionMailboxRoutingJobSidekiqFix
extend ActiveSupport::Concern
included do
sidekiq_options retry: false
end
end
2)イニシャライザのジョブクラスに含めます。
# config/initializers/extensions.rb
require Rails.root.join('lib', 'fixes', 'action_mailbox_routing_job_sidekiq_fix')
Rails.configuration.to_prepare do
ActionMailbox::RoutingJob.include ::ActionMailboxRoutingJobSidekiqFix
end