Module: SidekiqUniqueJobsJidLookup
- Defined in:
- app/services/sidekiq_unique_jobs_jid_lookup.rb
Overview
Resolves Sidekiq JIDs that currently hold a sidekiq-unique-jobs lock for the same
worker + args. Used when +perform_async+ returns +nil+ (reject-on-conflict) so
the user can be redirected to the in-flight job instead of a generic error.
See +config/initializers/sidekiq.rb+ global +until_and_while_executing+ /
client +on_conflict: :log+ — the client does not receive the "other" jid when a
duplicate is coalesced.
Class Method Summary collapse
- .active_jid_for_args(worker_class, *perform_args) ⇒ Object
- .active_sidekiq_status?(jid) ⇒ Boolean
- .deep_stringify_array(args) ⇒ Object
- .deep_stringify_keys(obj) ⇒ Object
-
.effective_lock_digest(worker_class, prepared_item) ⇒ Object
WhileExecuting mutates the digest with a :RUN suffix before keys are written (see SidekiqUniqueJobs::Lock::WhileExecuting#append_unique_key_suffix).
- .pick_active_jid(jids) ⇒ Object
- .prepared_item(worker_class, perform_args) ⇒ Object
- .resolved_lock_type(worker_class) ⇒ Object
Class Method Details
.active_jid_for_args(worker_class, *perform_args) ⇒ Object
11 12 13 14 15 16 17 18 19 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 11 def self.active_jid_for_args(worker_class, *perform_args) item = prepared_item(worker_class, perform_args) digest = effective_lock_digest(worker_class, item) lock = SidekiqUniqueJobs::Lock.new(digest) pick_active_jid(lock.all_jids) rescue StandardError => e Rails.logger.warn("[SidekiqUniqueJobsJidLookup] #{e.class}: #{e.}") nil end |
.active_sidekiq_status?(jid) ⇒ Boolean
56 57 58 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 56 def self.active_sidekiq_status?(jid) Sidekiq::Status.status(jid).in?(%i[queued working]) end |
.deep_stringify_array(args) ⇒ Object
60 61 62 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 60 def self.deep_stringify_array(args) args.map { |arg| deep_stringify_keys(arg) } end |
.deep_stringify_keys(obj) ⇒ Object
64 65 66 67 68 69 70 71 72 73 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 64 def self.deep_stringify_keys(obj) case obj when Hash obj.transform_keys(&:to_s).transform_values { |v| deep_stringify_keys(v) } when Array obj.map { |v| deep_stringify_keys(v) } else obj end end |
.effective_lock_digest(worker_class, prepared_item) ⇒ Object
WhileExecuting mutates the digest with a :RUN suffix before keys are written (see
SidekiqUniqueJobs::Lock::WhileExecuting#append_unique_key_suffix).
35 36 37 38 39 40 41 42 43 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 35 def self.effective_lock_digest(worker_class, prepared_item) digest = prepared_item[SidekiqUniqueJobs::LOCK_DIGEST] lock = resolved_lock_type(worker_class) if lock.to_s == 'while_executing' suffix = SidekiqUniqueJobs::Lock::WhileExecuting::RUN_SUFFIX digest = "#{digest}#{suffix}" unless digest.end_with?(suffix) end digest end |
.pick_active_jid(jids) ⇒ Object
50 51 52 53 54 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 50 def self.pick_active_jid(jids) return nil if jids.blank? jids.find { |jid| jid.present? && active_sidekiq_status?(jid) } end |
.prepared_item(worker_class, perform_args) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 21 def self.prepared_item(worker_class, perform_args) opts = worker_class..stringify_keys queue = (opts['queue'] || 'default').to_s item = { 'class' => worker_class.name, 'queue' => queue, 'args' => deep_stringify_array(perform_args) } SidekiqUniqueJobs::Job.prepare(item) item end |
.resolved_lock_type(worker_class) ⇒ Object
45 46 47 48 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 45 def self.resolved_lock_type(worker_class) worker_class..symbolize_keys[:lock] || Sidekiq..symbolize_keys[:lock] end |