sidekiq-unique-jobs 3.0.14 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sidekiq-unique-jobs might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.editorconfig +14 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +8 -0
- data/.simplecov +12 -0
- data/.travis.yml +16 -8
- data/Appraisals +10 -10
- data/CHANGELOG.md +11 -0
- data/Gemfile +11 -1
- data/README.md +58 -4
- data/Rakefile +2 -1
- data/circle.yml +36 -0
- data/gemfiles/sidekiq_2.17.gemfile +8 -1
- data/gemfiles/sidekiq_3.0.gemfile +8 -1
- data/gemfiles/sidekiq_3.1.gemfile +8 -1
- data/gemfiles/sidekiq_3.2.gemfile +8 -1
- data/gemfiles/sidekiq_3.3.gemfile +8 -1
- data/gemfiles/sidekiq_develop.gemfile +8 -1
- data/lib/sidekiq-unique-jobs.rb +44 -9
- data/lib/sidekiq_unique_jobs/client/middleware.rb +47 -0
- data/lib/sidekiq_unique_jobs/config.rb +9 -33
- data/lib/sidekiq_unique_jobs/core_ext.rb +46 -0
- data/lib/sidekiq_unique_jobs/lock.rb +10 -0
- data/lib/sidekiq_unique_jobs/lock/time_calculator.rb +44 -0
- data/lib/sidekiq_unique_jobs/lock/until_executed.rb +56 -0
- data/lib/sidekiq_unique_jobs/lock/until_executing.rb +6 -0
- data/lib/sidekiq_unique_jobs/lock/until_timeout.rb +10 -0
- data/lib/sidekiq_unique_jobs/lock/while_executing.rb +31 -0
- data/lib/sidekiq_unique_jobs/middleware.rb +30 -14
- data/lib/sidekiq_unique_jobs/normalizer.rb +7 -0
- data/lib/sidekiq_unique_jobs/options_with_fallback.rb +36 -0
- data/lib/sidekiq_unique_jobs/run_lock_failed.rb +1 -0
- data/lib/sidekiq_unique_jobs/scripts.rb +50 -0
- data/lib/sidekiq_unique_jobs/server/middleware.rb +73 -0
- data/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb +71 -9
- data/lib/sidekiq_unique_jobs/testing.rb +34 -0
- data/lib/sidekiq_unique_jobs/testing/sidekiq_overrides.rb +63 -0
- data/lib/sidekiq_unique_jobs/unique_args.rb +132 -0
- data/lib/sidekiq_unique_jobs/unlockable.rb +26 -0
- data/lib/sidekiq_unique_jobs/version.rb +1 -1
- data/redis/aquire_lock.lua +9 -0
- data/redis/release_lock.lua +14 -0
- data/redis/synchronize.lua +15 -0
- data/sidekiq-unique-jobs.gemspec +2 -4
- data/spec/lib/sidekiq_unique_jobs/client/middleware_spec.rb +195 -0
- data/spec/lib/sidekiq_unique_jobs/core_ext_spec.rb +25 -0
- data/spec/lib/sidekiq_unique_jobs/lock/time_calculator_spec.rb +81 -0
- data/spec/lib/sidekiq_unique_jobs/lock/while_executing_spec.rb +48 -0
- data/spec/lib/sidekiq_unique_jobs/normalizer_spec.rb +21 -0
- data/spec/lib/sidekiq_unique_jobs/scripts_spec.rb +74 -0
- data/spec/lib/sidekiq_unique_jobs/server/middleware_spec.rb +100 -0
- data/spec/lib/{sidekiq_testing_enabled_spec.rb → sidekiq_unique_jobs/sidekiq_testing_enabled_spec.rb} +29 -68
- data/spec/lib/sidekiq_unique_jobs/sidekiq_unique_ext_spec.rb +79 -0
- data/spec/lib/sidekiq_unique_jobs/sidekiq_unique_jobs_spec.rb +36 -0
- data/spec/lib/sidekiq_unique_jobs/unique_args_spec.rb +106 -0
- data/spec/spec_helper.rb +40 -10
- data/spec/support/matchers/redis_matchers.rb +19 -0
- data/spec/support/ruby_meta.rb +10 -0
- data/spec/support/sidekiq_meta.rb +11 -2
- data/spec/support/unique_macros.rb +52 -0
- data/spec/workers/after_unlock_worker.rb +13 -0
- data/spec/{support → workers}/after_yield_worker.rb +6 -2
- data/spec/{support → workers}/another_unique_worker.rb +1 -1
- data/spec/workers/before_yield_worker.rb +9 -0
- data/spec/workers/expiring_worker.rb +4 -0
- data/spec/workers/inline_expiration_worker.rb +8 -0
- data/spec/workers/inline_unlock_order_worker.rb +8 -0
- data/spec/workers/inline_worker.rb +8 -0
- data/spec/workers/just_a_worker.rb +8 -0
- data/spec/workers/main_job.rb +8 -0
- data/spec/workers/my_unique_worker.rb +8 -0
- data/spec/{support → workers}/my_worker.rb +0 -0
- data/spec/workers/plain_class.rb +4 -0
- data/spec/workers/queue_worker.rb +6 -0
- data/spec/workers/queue_worker_with_filter_method.rb +7 -0
- data/spec/workers/queue_worker_with_filter_proc.rb +11 -0
- data/spec/workers/run_lock_with_retries_worker.rb +12 -0
- data/spec/workers/run_lock_worker.rb +7 -0
- data/spec/workers/test_class.rb +4 -0
- data/spec/workers/unique_job_with_filter_method.rb +18 -0
- data/spec/workers/unique_on_all_queues_worker.rb +13 -0
- data/spec/{support → workers}/unique_worker.rb +1 -1
- data/spec/workers/while_executing_worker.rb +13 -0
- metadata +65 -39
- data/lib/sidekiq_unique_jobs/connectors.rb +0 -16
- data/lib/sidekiq_unique_jobs/connectors/redis_pool.rb +0 -11
- data/lib/sidekiq_unique_jobs/connectors/sidekiq_redis.rb +0 -9
- data/lib/sidekiq_unique_jobs/connectors/testing.rb +0 -11
- data/lib/sidekiq_unique_jobs/inline_testing.rb +0 -12
- data/lib/sidekiq_unique_jobs/middleware/client/strategies/testing_inline.rb +0 -25
- data/lib/sidekiq_unique_jobs/middleware/client/strategies/unique.rb +0 -105
- data/lib/sidekiq_unique_jobs/middleware/client/unique_jobs.rb +0 -43
- data/lib/sidekiq_unique_jobs/middleware/server/unique_jobs.rb +0 -69
- data/lib/sidekiq_unique_jobs/payload_helper.rb +0 -42
- data/lib/sidekiq_unique_jobs/sidekiq_test_overrides.rb +0 -101
- data/spec/lib/client_spec.rb +0 -193
- data/spec/lib/middleware/server/unique_jobs_spec.rb +0 -112
- data/spec/lib/sidekiq_unique_ext_spec.rb +0 -70
- data/spec/lib/unlock_order_spec.rb +0 -64
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'digest'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module SidekiqUniqueJobs
|
5
|
+
module Server
|
6
|
+
class Middleware
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :Sidekiq, :logger
|
9
|
+
def_instance_delegator :@worker, :class, :worker_class
|
10
|
+
|
11
|
+
include OptionsWithFallback
|
12
|
+
|
13
|
+
def call(worker, item, queue, redis_pool = nil, &blk)
|
14
|
+
@worker = worker
|
15
|
+
@redis_pool = redis_pool
|
16
|
+
@queue = queue
|
17
|
+
@item = item
|
18
|
+
|
19
|
+
send(unique_lock, &blk)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :redis_pool, :worker, :item, :worker_class
|
25
|
+
|
26
|
+
def until_executing
|
27
|
+
unlock
|
28
|
+
yield
|
29
|
+
end
|
30
|
+
|
31
|
+
def until_executed(&block)
|
32
|
+
operative = true
|
33
|
+
after_yield_yield(&block)
|
34
|
+
rescue Sidekiq::Shutdown
|
35
|
+
operative = false
|
36
|
+
raise
|
37
|
+
ensure
|
38
|
+
unlock if operative
|
39
|
+
end
|
40
|
+
|
41
|
+
def after_yield_yield
|
42
|
+
yield
|
43
|
+
end
|
44
|
+
|
45
|
+
def while_executing
|
46
|
+
lock.synchronize do
|
47
|
+
yield
|
48
|
+
end
|
49
|
+
rescue SidekiqUniqueJobs::RunLockFailed
|
50
|
+
return reschedule if reschedule_on_lock_fail
|
51
|
+
raise
|
52
|
+
end
|
53
|
+
|
54
|
+
def until_timeout
|
55
|
+
yield if block_given?
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
def unlock
|
61
|
+
after_unlock_hook if lock.unlock(:server)
|
62
|
+
end
|
63
|
+
|
64
|
+
def after_unlock_hook
|
65
|
+
worker.after_unlock if worker.respond_to?(:after_unlock)
|
66
|
+
end
|
67
|
+
|
68
|
+
def reschedule
|
69
|
+
Sidekiq::Client.new(redis_pool).raw_push([item])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -1,30 +1,81 @@
|
|
1
1
|
require 'sidekiq/api'
|
2
2
|
|
3
3
|
module Sidekiq
|
4
|
-
|
4
|
+
module UnlockMethod
|
5
|
+
def unlock(item)
|
6
|
+
SidekiqUniqueJobs::Unlockable.unlock(item['unique_digest'.freeze], item['jid'.freeze])
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class SortedEntry
|
5
11
|
module UniqueExtension
|
6
12
|
def self.included(base)
|
7
13
|
base.class_eval do
|
14
|
+
include UnlockMethod
|
8
15
|
alias_method :delete_orig, :delete
|
9
16
|
alias_method :delete, :delete_ext
|
17
|
+
alias_method :remove_job_orig, :remove_job
|
18
|
+
alias_method :remove_job, :remove_job_ext
|
10
19
|
end
|
11
20
|
end
|
12
21
|
|
13
22
|
def delete_ext
|
14
|
-
unlock(
|
15
|
-
|
23
|
+
unlock(item) if delete_orig
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def remove_job_ext
|
29
|
+
remove_job_orig do |message|
|
30
|
+
unlock(Sidekiq.load_json(message))
|
31
|
+
yield message
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
include UniqueExtension if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('3.1')
|
37
|
+
end
|
38
|
+
|
39
|
+
class ScheduledSet
|
40
|
+
module UniqueExtension
|
41
|
+
def self.included(base)
|
42
|
+
base.class_eval do
|
43
|
+
include UnlockMethod
|
44
|
+
alias_method :delete_orig, :delete
|
45
|
+
alias_method :delete, :delete_ext
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def delete_ext
|
50
|
+
unlock(item) if delete_orig
|
16
51
|
end
|
17
52
|
|
18
|
-
|
53
|
+
def remove_job_ext
|
54
|
+
remove_job_orig do |message|
|
55
|
+
unlock(Sidekiq.load_json(message))
|
56
|
+
yield message
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
include UniqueExtension if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('3.1')
|
61
|
+
end
|
19
62
|
|
20
|
-
|
21
|
-
|
63
|
+
class Job
|
64
|
+
module UniqueExtension
|
65
|
+
def self.included(base)
|
66
|
+
base.class_eval do
|
67
|
+
include UnlockMethod
|
68
|
+
alias_method :delete_orig, :delete
|
69
|
+
alias_method :delete, :delete_ext
|
70
|
+
end
|
22
71
|
end
|
23
72
|
|
24
|
-
def
|
25
|
-
|
73
|
+
def delete_ext
|
74
|
+
unlock(item)
|
75
|
+
delete_orig
|
26
76
|
end
|
27
77
|
end
|
78
|
+
|
28
79
|
include UniqueExtension
|
29
80
|
end
|
30
81
|
|
@@ -32,6 +83,7 @@ module Sidekiq
|
|
32
83
|
module UniqueExtension
|
33
84
|
def self.included(base)
|
34
85
|
base.class_eval do
|
86
|
+
include UnlockMethod
|
35
87
|
alias_method :clear_orig, :clear
|
36
88
|
alias_method :clear, :clear_ext
|
37
89
|
end
|
@@ -50,17 +102,27 @@ module Sidekiq
|
|
50
102
|
module UniqueExtension
|
51
103
|
def self.included(base)
|
52
104
|
base.class_eval do
|
105
|
+
include UnlockMethod
|
53
106
|
if base.method_defined?(:clear)
|
54
107
|
alias_method :clear_orig, :clear
|
55
108
|
alias_method :clear, :clear_ext
|
56
109
|
end
|
110
|
+
|
111
|
+
if base.method_defined?(:delete_by_value)
|
112
|
+
alias_method :delete_by_value_orig, :delete_by_value
|
113
|
+
alias_method :delete_by_value, :delete_by_value_ext
|
114
|
+
end
|
57
115
|
end
|
58
116
|
end
|
59
117
|
|
60
118
|
def clear_ext
|
61
|
-
each(&:
|
119
|
+
each(&:delete)
|
62
120
|
clear_orig
|
63
121
|
end
|
122
|
+
|
123
|
+
def delete_by_value_ext(name, value)
|
124
|
+
unlock(JSON.parse(value)) if delete_by_value_orig(name, value)
|
125
|
+
end
|
64
126
|
end
|
65
127
|
|
66
128
|
include UniqueExtension
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'sidekiq_unique_jobs/testing/sidekiq_overrides'
|
2
|
+
|
3
|
+
module SidekiqUniqueJobs
|
4
|
+
module Client
|
5
|
+
class Middleware
|
6
|
+
alias_method :call_real, :call
|
7
|
+
def call(worker_class, item, queue, redis_pool = nil)
|
8
|
+
worker_class = SidekiqUniqueJobs.worker_class_constantize(worker_class)
|
9
|
+
|
10
|
+
if Sidekiq::Testing.inline?
|
11
|
+
_server.call(worker_class.new, item, queue, redis_pool) do
|
12
|
+
call_real(worker_class, item, queue, redis_pool) do
|
13
|
+
yield
|
14
|
+
end
|
15
|
+
end
|
16
|
+
else
|
17
|
+
call_real(worker_class, item, queue, redis_pool) do
|
18
|
+
yield
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def _server
|
24
|
+
SidekiqUniqueJobs::Server::Middleware.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Testing
|
30
|
+
def mocking!
|
31
|
+
require 'sidekiq_unique_jobs/testing/mocking'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'sidekiq/testing'
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Worker
|
5
|
+
module ClassMethods
|
6
|
+
include SidekiqUniqueJobs::Unlockable
|
7
|
+
|
8
|
+
# Drain and run all jobs for this worker
|
9
|
+
def drain
|
10
|
+
while (job = jobs.shift)
|
11
|
+
worker = new
|
12
|
+
worker.jid = job['jid']
|
13
|
+
worker.bid = job['bid'] if worker.respond_to?(:bid=)
|
14
|
+
execute_job(worker, job['args'])
|
15
|
+
unlock(job['unique_digest'], job['jid']) if Sidekiq::Testing.fake?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Pop out a single job and perform it
|
20
|
+
def perform_one
|
21
|
+
fail(EmptyQueueError, 'perform_one called with empty job queue') if jobs.empty?
|
22
|
+
job = jobs.shift
|
23
|
+
worker = new
|
24
|
+
worker.jid = job['jid']
|
25
|
+
worker.bid = job['bid'] if worker.respond_to?(:bid=)
|
26
|
+
execute_job(worker, job['args'])
|
27
|
+
unlock(job['unique_digest'], job['jid']) if Sidekiq::Testing.fake?
|
28
|
+
end
|
29
|
+
|
30
|
+
# Clear all jobs for this worker
|
31
|
+
def clear
|
32
|
+
jobs.each do |job|
|
33
|
+
unlock(job['unique_digest'], job['jid']) if Sidekiq::Testing.fake?
|
34
|
+
end
|
35
|
+
jobs.clear
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module Overrides
|
40
|
+
def self.included(base)
|
41
|
+
base.extend Sidekiq::Worker::Overrides::ClassMethods
|
42
|
+
base.class_eval do
|
43
|
+
class << self
|
44
|
+
alias_method :clear_all_orig, :clear_all
|
45
|
+
alias_method :clear_all, :clear_all_ext
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module ClassMethods
|
51
|
+
def clear_all_ext
|
52
|
+
Sidekiq.redis do |c|
|
53
|
+
unique_keys = c.keys("#{SidekiqUniqueJobs.config.unique_prefix}:*")
|
54
|
+
c.del(*unique_keys) unless unique_keys.empty?
|
55
|
+
end
|
56
|
+
clear_all_orig
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
include Overrides
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'sidekiq_unique_jobs/normalizer'
|
2
|
+
|
3
|
+
module SidekiqUniqueJobs
|
4
|
+
# This class exists to be testable and the entire api should be considered private
|
5
|
+
# rubocop:disable ClassLength
|
6
|
+
class UniqueArgs
|
7
|
+
extend Forwardable
|
8
|
+
include Normalizer
|
9
|
+
|
10
|
+
def_delegators :SidekiqUniqueJobs, :config, :worker_class_constantize
|
11
|
+
def_delegators :'Sidekiq.logger', :logger, :debug, :warn, :error, :fatal
|
12
|
+
|
13
|
+
def self.digest(item)
|
14
|
+
new(item).unique_digest
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(job)
|
18
|
+
Sidekiq::Logging.with_context(self.class.name) do
|
19
|
+
@item = job
|
20
|
+
@worker_class ||= worker_class_constantize(@item['class'.freeze])
|
21
|
+
@item['unique_prefix'.freeze] ||= unique_prefix
|
22
|
+
@item['unique_args'.freeze] ||= unique_args(@item['args'.freeze])
|
23
|
+
@item['unique_digest'.freeze] ||= unique_digest
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def unique_digest
|
28
|
+
@unique_digest ||= begin
|
29
|
+
digest = Digest::MD5.hexdigest(Sidekiq.dump_json(digestable_hash))
|
30
|
+
digest = "#{unique_prefix}:#{digest}"
|
31
|
+
debug { "#{__method__} : #{digestable_hash} into #{digest}" }
|
32
|
+
digest
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def unique_prefix
|
37
|
+
return config.unique_prefix unless sidekiq_worker_class?
|
38
|
+
@worker_class.get_sidekiq_options['unique_prefix'.freeze] || config.unique_prefix
|
39
|
+
end
|
40
|
+
|
41
|
+
def digestable_hash
|
42
|
+
hash = @item.slice('class', 'queue', 'unique_args')
|
43
|
+
|
44
|
+
if unique_on_all_queues?
|
45
|
+
debug { "uniqueness specified across all queues (deleting queue: #{@item['queue']} from hash)" }
|
46
|
+
hash.delete('queue')
|
47
|
+
end
|
48
|
+
hash
|
49
|
+
end
|
50
|
+
|
51
|
+
def unique_args(args)
|
52
|
+
if unique_args_enabled?
|
53
|
+
filtered_args(args)
|
54
|
+
else
|
55
|
+
debug { "#{__method__} : unique arguments disabled" }
|
56
|
+
args
|
57
|
+
end
|
58
|
+
rescue NameError
|
59
|
+
# fallback to not filtering args when class can't be instantiated
|
60
|
+
return args
|
61
|
+
end
|
62
|
+
|
63
|
+
def unique_on_all_queues?
|
64
|
+
return unless sidekiq_worker_class?
|
65
|
+
return unless unique_args_enabled?
|
66
|
+
@worker_class.get_sidekiq_options['unique_on_all_queues'.freeze]
|
67
|
+
end
|
68
|
+
|
69
|
+
def unique_args_enabled?
|
70
|
+
unique_args_enabled_in_worker? ||
|
71
|
+
config.unique_args_enabled
|
72
|
+
end
|
73
|
+
|
74
|
+
def unique_args_enabled_in_worker?
|
75
|
+
return unless sidekiq_worker_class?
|
76
|
+
@worker_class.get_sidekiq_options['unique_args_enabled'.freeze] ||
|
77
|
+
@worker_class.get_sidekiq_options['unique_args'.freeze]
|
78
|
+
end
|
79
|
+
|
80
|
+
def sidekiq_worker_class?
|
81
|
+
if @worker_class.respond_to?(:get_sidekiq_options)
|
82
|
+
true
|
83
|
+
else
|
84
|
+
debug { "#{@worker_class} does not respond to :get_sidekiq_options" }
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Filters unique arguments by proc or symbol
|
90
|
+
# returns provided arguments for other configurations
|
91
|
+
def filtered_args(args)
|
92
|
+
return args if args.empty?
|
93
|
+
json_args = Normalizer.jsonify(args)
|
94
|
+
debug { "#filtered_args #{args} => #{json_args}" }
|
95
|
+
|
96
|
+
case unique_args_method
|
97
|
+
when Proc
|
98
|
+
filter_by_proc(json_args)
|
99
|
+
when Symbol
|
100
|
+
filter_by_symbol(json_args)
|
101
|
+
else
|
102
|
+
debug { 'arguments not filtered (the combined arguments count towards uniqueness)' }
|
103
|
+
json_args
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def filter_by_proc(args)
|
108
|
+
filter_args = unique_args_method.call(args)
|
109
|
+
debug { "#{__method__} : #{args} -> #{filter_args}" }
|
110
|
+
filter_args
|
111
|
+
end
|
112
|
+
|
113
|
+
def filter_by_symbol(args)
|
114
|
+
unless @worker_class.respond_to?(unique_args_method)
|
115
|
+
warn do
|
116
|
+
"#{__method__} : #{unique_args_method}) not defined in #{@worker_class} " \
|
117
|
+
"returning #{args} unchanged"
|
118
|
+
end
|
119
|
+
return args
|
120
|
+
end
|
121
|
+
|
122
|
+
filter_args = @worker_class.send(unique_args_method, args)
|
123
|
+
debug { "#{__method__} : #{unique_args_method}(#{args}) => #{filter_args}" }
|
124
|
+
filter_args
|
125
|
+
end
|
126
|
+
|
127
|
+
def unique_args_method
|
128
|
+
@unique_args_method ||=
|
129
|
+
@worker_class.get_sidekiq_options['unique_args'.freeze] if sidekiq_worker_class?
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SidekiqUniqueJobs
|
2
|
+
module Unlockable
|
3
|
+
module_function
|
4
|
+
|
5
|
+
# rubocop:disable MethodLength
|
6
|
+
def unlock(unique_key, jid, redis_pool = nil)
|
7
|
+
result = Scripts.call(:release_lock, redis_pool,
|
8
|
+
keys: [unique_key],
|
9
|
+
argv: [jid])
|
10
|
+
case result
|
11
|
+
when 1
|
12
|
+
Sidekiq.logger.debug { "successfully unlocked #{unique_key}" }
|
13
|
+
true
|
14
|
+
when 0
|
15
|
+
Sidekiq.logger.debug { "expiring lock #{unique_key} is not owned by #{jid}" }
|
16
|
+
false
|
17
|
+
when -1
|
18
|
+
Sidekiq.logger.debug { "#{unique_key} is not a known key" }
|
19
|
+
false
|
20
|
+
else
|
21
|
+
fail "#{__method__} returned an unexpected value (#{result})"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
# rubocop:enable MethodLength
|
25
|
+
end
|
26
|
+
end
|