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+ /
+on_conflict: :reject+ — the client does not receive the "other" jid on rejection.
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
10 11 12 13 14 15 16 17 18 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 10 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
55 56 57 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 55 def self.active_sidekiq_status?(jid) Sidekiq::Status.status(jid).in?(%i[queued working]) end |
.deep_stringify_array(args) ⇒ Object
59 60 61 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 59 def self.deep_stringify_array(args) args.map { |arg| deep_stringify_keys(arg) } end |
.deep_stringify_keys(obj) ⇒ Object
63 64 65 66 67 68 69 70 71 72 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 63 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).
34 35 36 37 38 39 40 41 42 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 34 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
49 50 51 52 53 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 49 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
20 21 22 23 24 25 26 27 28 29 30 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 20 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
44 45 46 47 |
# File 'app/services/sidekiq_unique_jobs_jid_lookup.rb', line 44 def self.resolved_lock_type(worker_class) worker_class..symbolize_keys[:lock] || Sidekiq..symbolize_keys[:lock] end |