これを使います。
コード
class Worker
include Sidekiq::Workers
sidekiq_options lock: :while_executing, on_conflict: :hogefuga_strategy,
lock_args_method: :lock_args
def perform(id, piyo)
# Do work
end
end
このコードでは、id
, piyo
が同一のジョブが並列実行されないように制御されます。もし衝突が発生した場合、hogefuga_strategy
が呼び出されてジョブは消費されます。
衝突時
lib/strategies/hogefuga_strategy.rb
module Strategies
class HogeFugaStrategy < SidekiqUniqueJobs::OnConflict::Strategy
def call
Worker.perform_async(
item['args'][0],
item['args'][1]
)
end
end
end
このようなコードを組むと、衝突したらまたキューに詰めなおすという戦略になります。重複するジョブが多い場合はパフォーマンスに影響を与えますが、同じジョブが同時に実行されることはなく、ジョブが消失することもありません。
おわり
普通に考えると、並列するとまずいやつ用のキューを用意して直列実行できるような構成を取るべきですね。泣