sidekiq-unique-jobs 5.0.11 → 6.0.0.rc1
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/.codeclimate.yml +17 -9
- data/.gitignore +1 -3
- data/.reek +105 -0
- data/.rubocop.yml +36 -1
- data/.simplecov +7 -2
- data/.travis.yml +11 -10
- data/Appraisals +3 -7
- data/CHANGELOG.md +17 -0
- data/Gemfile +16 -13
- data/Guardfile +55 -0
- data/README.md +85 -73
- data/examples/another_unique_job.rb +13 -0
- data/examples/custom_queue_job.rb +12 -0
- data/examples/custom_queue_job_with_filter_method.rb +13 -0
- data/examples/custom_queue_job_with_filter_proc.rb +16 -0
- data/examples/expiring_job.rb +12 -0
- data/examples/inline_worker.rb +12 -0
- data/examples/just_a_worker.rb +13 -0
- data/examples/long_running_job.rb +12 -0
- data/examples/main_job.rb +13 -0
- data/examples/my_job.rb +12 -0
- data/examples/my_unique_job.rb +16 -0
- data/examples/my_unique_job_with_filter_method.rb +21 -0
- data/examples/my_unique_job_with_filter_proc.rb +19 -0
- data/examples/notify_worker.rb +14 -0
- data/examples/plain_class.rb +13 -0
- data/examples/simple_worker.rb +15 -0
- data/examples/spawn_simple_worker.rb +12 -0
- data/examples/test_class.rb +9 -0
- data/examples/unique_across_workers_job.rb +20 -0
- data/examples/unique_job_with_conditional_parameter.rb +18 -0
- data/examples/unique_job_with_filter_method.rb +18 -0
- data/examples/unique_job_with_nil_unique_args.rb +20 -0
- data/examples/unique_job_with_no_unique_args_method.rb +16 -0
- data/examples/unique_job_withthout_unique_args_parameter.rb +18 -0
- data/examples/unique_on_all_queues_job.rb +16 -0
- data/examples/until_and_while_executing_job.rb +13 -0
- data/examples/until_executed_2_job.rb +24 -0
- data/examples/until_executed_job.rb +25 -0
- data/examples/until_executing_job.rb +11 -0
- data/examples/until_expired_job.rb +12 -0
- data/examples/until_global_expired_job.rb +12 -0
- data/examples/while_executing_job.rb +15 -0
- data/examples/while_executing_reject_job.rb +14 -0
- data/examples/without_argument_job.rb +13 -0
- data/lib/sidekiq-unique-jobs.rb +1 -91
- data/lib/sidekiq/simulator.rb +15 -16
- data/lib/sidekiq_unique_jobs.rb +79 -0
- data/lib/sidekiq_unique_jobs/cli.rb +9 -18
- data/lib/sidekiq_unique_jobs/client/middleware.rb +16 -18
- data/lib/sidekiq_unique_jobs/connection.rb +18 -0
- data/lib/sidekiq_unique_jobs/constants.rb +13 -17
- data/lib/sidekiq_unique_jobs/core_ext.rb +28 -55
- data/lib/sidekiq_unique_jobs/exceptions.rb +30 -0
- data/lib/sidekiq_unique_jobs/lock/base_lock.rb +84 -0
- data/lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb +11 -6
- data/lib/sidekiq_unique_jobs/lock/until_executed.rb +6 -58
- data/lib/sidekiq_unique_jobs/lock/until_executing.rb +6 -5
- data/lib/sidekiq_unique_jobs/lock/until_expired.rb +17 -0
- data/lib/sidekiq_unique_jobs/lock/while_executing.rb +20 -34
- data/lib/sidekiq_unique_jobs/lock/while_executing_reject.rb +78 -0
- data/lib/sidekiq_unique_jobs/lock/while_executing_requeue.rb +20 -0
- data/lib/sidekiq_unique_jobs/locksmith.rb +149 -0
- data/lib/sidekiq_unique_jobs/logging.rb +30 -0
- data/lib/sidekiq_unique_jobs/options_with_fallback.rb +27 -41
- data/lib/sidekiq_unique_jobs/scripts.rb +25 -24
- data/lib/sidekiq_unique_jobs/server/middleware.rb +12 -20
- data/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb +5 -5
- data/lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb +42 -0
- data/lib/sidekiq_unique_jobs/testing.rb +40 -50
- data/lib/sidekiq_unique_jobs/timeout.rb +15 -0
- data/lib/sidekiq_unique_jobs/timeout/calculator.rb +49 -0
- data/lib/sidekiq_unique_jobs/unique_args.rb +33 -77
- data/lib/sidekiq_unique_jobs/unlockable.rb +5 -14
- data/lib/sidekiq_unique_jobs/util.rb +28 -90
- data/lib/sidekiq_unique_jobs/version.rb +1 -1
- data/redis/acquire_lock.lua +5 -3
- data/redis/create.lua +58 -0
- data/redis/delete.lua +11 -0
- data/redis/release_stale_locks.lua +90 -0
- data/redis/signal.lua +21 -0
- data/sidekiq-unique-jobs.gemspec +15 -8
- metadata +108 -32
- data/lib/sidekiq_unique_jobs/config.rb +0 -17
- data/lib/sidekiq_unique_jobs/lock.rb +0 -12
- data/lib/sidekiq_unique_jobs/lock/until_timeout.rb +0 -17
- data/lib/sidekiq_unique_jobs/run_lock_failed.rb +0 -3
- data/lib/sidekiq_unique_jobs/script_mock.rb +0 -66
- data/lib/sidekiq_unique_jobs/scripts/acquire_lock.rb +0 -47
- data/lib/sidekiq_unique_jobs/scripts/release_lock.rb +0 -49
- data/lib/sidekiq_unique_jobs/testing/sidekiq_overrides.rb +0 -50
- data/lib/sidekiq_unique_jobs/timeout_calculator.rb +0 -67
- data/redis/synchronize.lua +0 -16
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
|
5
|
+
class SimpleWorker
|
6
|
+
include Sidekiq::Worker
|
7
|
+
sidekiq_options queue: :default,
|
8
|
+
unique: :until_executed,
|
9
|
+
unique_args: ->(args) { [args.first] }
|
10
|
+
|
11
|
+
def perform(args)
|
12
|
+
sleep 5
|
13
|
+
[args]
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
|
5
|
+
# This class showcase a job that is considered unique disregarding any worker classes.
|
6
|
+
# Currently it will only be compared to other jobs that are disregarding worker classes.
|
7
|
+
# If one were to compare the unique keys generated against a job that doesn't have the
|
8
|
+
# worker class removed it won't work.
|
9
|
+
#
|
10
|
+
# The following specs cover this functionality:
|
11
|
+
# - https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/lib/sidekiq_unique_jobs/client/middleware_spec.rb
|
12
|
+
# - https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/lib/sidekiq_unique_jobs/unique_args_spec.rb
|
13
|
+
class UniqueAcrossWorkersJob
|
14
|
+
include Sidekiq::Worker
|
15
|
+
sidekiq_options unique: :until_executed, unique_across_workers: true
|
16
|
+
|
17
|
+
def perform(one, two)
|
18
|
+
[one, two]
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
|
5
|
+
class UniqueJobWithoutUniqueArgsParameter
|
6
|
+
include Sidekiq::Worker
|
7
|
+
sidekiq_options queue: :customqueue,
|
8
|
+
retry: true,
|
9
|
+
backtrace: true,
|
10
|
+
unique: :until_executed,
|
11
|
+
unique_args: :unique_args
|
12
|
+
|
13
|
+
def perform(conditional = nil)
|
14
|
+
[conditional]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.unique_args; end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
|
5
|
+
class UniqueJobWithFilterMethod
|
6
|
+
include Sidekiq::Worker
|
7
|
+
sidekiq_options queue: :customqueue, retry: 1, backtrace: 10,
|
8
|
+
unique: :while_executing, unique_args: :filtered_args
|
9
|
+
|
10
|
+
def perform(*)
|
11
|
+
# NO-OP
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.filtered_args(args)
|
15
|
+
options = args.extract_options!
|
16
|
+
[args.first, options['type']]
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
|
5
|
+
class UniqueJobWithNilUniqueArgs
|
6
|
+
include Sidekiq::Worker
|
7
|
+
sidekiq_options queue: :customqueue,
|
8
|
+
retry: true,
|
9
|
+
backtrace: true,
|
10
|
+
unique: :until_executed,
|
11
|
+
unique_args: :unique_args
|
12
|
+
|
13
|
+
def perform(args)
|
14
|
+
[args]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.unique_args(_args)
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
|
5
|
+
class UniqueJobWithNoUniqueArgsMethod
|
6
|
+
include Sidekiq::Worker
|
7
|
+
sidekiq_options queue: :customqueue,
|
8
|
+
retry: true,
|
9
|
+
backtrace: true,
|
10
|
+
unique: :until_executed,
|
11
|
+
unique_args: :filtered_args
|
12
|
+
|
13
|
+
def perform(one, two)
|
14
|
+
[one, two]
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
|
5
|
+
class UniqueJobWithoutUniqueArgsParameter
|
6
|
+
include Sidekiq::Worker
|
7
|
+
sidekiq_options queue: :customqueue,
|
8
|
+
retry: true,
|
9
|
+
backtrace: true,
|
10
|
+
unique: :until_executed,
|
11
|
+
unique_args: :unique_args
|
12
|
+
|
13
|
+
def perform(optional = true)
|
14
|
+
# NO-OP
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.unique_args; end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
|
5
|
+
# This class showcase a job that is considered unique disregarding any queue.
|
6
|
+
# Currently it will only be compared to other jobs that are disregarding queue.
|
7
|
+
# If one were to compare the unique keys generated against a job that doesn't have the
|
8
|
+
# queue removed it won't work.
|
9
|
+
class UniqueOnAllQueuesJob
|
10
|
+
include Sidekiq::Worker
|
11
|
+
sidekiq_options unique: :until_executed, unique_on_all_queues: true
|
12
|
+
|
13
|
+
def perform(one, two, three = nil)
|
14
|
+
[one, two, three]
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
|
5
|
+
# This class will lock until the job is successfully executed
|
6
|
+
#
|
7
|
+
# It will wait for 0 seconds to acquire a lock and it will expire the unique key after 2 seconds
|
8
|
+
#
|
9
|
+
class UntilExecuted2Job
|
10
|
+
include Sidekiq::Worker
|
11
|
+
sidekiq_options queue: :working,
|
12
|
+
retry: 1,
|
13
|
+
backtrace: 10,
|
14
|
+
unique: :until_executed,
|
15
|
+
lock_timeout: 0
|
16
|
+
|
17
|
+
def perform(one, two)
|
18
|
+
[one, two]
|
19
|
+
end
|
20
|
+
|
21
|
+
def after_unlock
|
22
|
+
# NO OP
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nocov:
|
4
|
+
|
5
|
+
# This class will lock until the job is successfully executed
|
6
|
+
#
|
7
|
+
# It will wait for 0 seconds to acquire a lock and it will expire the unique key after 2 seconds
|
8
|
+
#
|
9
|
+
class UntilExecutedJob
|
10
|
+
include Sidekiq::Worker
|
11
|
+
sidekiq_options queue: :working,
|
12
|
+
retry: 1,
|
13
|
+
backtrace: 10,
|
14
|
+
unique: :until_executed,
|
15
|
+
lock_timeout: 0,
|
16
|
+
lock_expiration: 5000
|
17
|
+
|
18
|
+
def perform(one, two = nil)
|
19
|
+
[one, two]
|
20
|
+
end
|
21
|
+
|
22
|
+
def after_unlock
|
23
|
+
# NO OP
|
24
|
+
end
|
25
|
+
end
|
data/lib/sidekiq-unique-jobs.rb
CHANGED
@@ -1,93 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'forwardable'
|
5
|
-
require 'sidekiq_unique_jobs/version'
|
6
|
-
require 'sidekiq_unique_jobs/constants'
|
7
|
-
require 'sidekiq_unique_jobs/util'
|
8
|
-
require 'sidekiq_unique_jobs/cli'
|
9
|
-
require 'sidekiq_unique_jobs/core_ext'
|
10
|
-
require 'sidekiq_unique_jobs/timeout_calculator'
|
11
|
-
require 'sidekiq_unique_jobs/options_with_fallback'
|
12
|
-
require 'sidekiq_unique_jobs/scripts'
|
13
|
-
require 'sidekiq_unique_jobs/unique_args'
|
14
|
-
require 'sidekiq_unique_jobs/unlockable'
|
15
|
-
require 'sidekiq_unique_jobs/lock'
|
16
|
-
require 'sidekiq_unique_jobs/middleware'
|
17
|
-
require 'sidekiq_unique_jobs/config'
|
18
|
-
require 'sidekiq_unique_jobs/sidekiq_unique_ext'
|
19
|
-
|
20
|
-
require 'ostruct'
|
21
|
-
|
22
|
-
module SidekiqUniqueJobs
|
23
|
-
module_function
|
24
|
-
|
25
|
-
def config
|
26
|
-
@config ||= Config.new(
|
27
|
-
unique_prefix: 'uniquejobs',
|
28
|
-
default_queue_lock_expiration: 30 * 60,
|
29
|
-
default_run_lock_expiration: 60,
|
30
|
-
default_lock: :while_executing,
|
31
|
-
redis_test_mode: :redis, # :mock
|
32
|
-
raise_unique_args_errors: false,
|
33
|
-
)
|
34
|
-
end
|
35
|
-
|
36
|
-
def logger
|
37
|
-
Sidekiq.logger
|
38
|
-
end
|
39
|
-
|
40
|
-
def default_lock
|
41
|
-
config.default_lock
|
42
|
-
end
|
43
|
-
|
44
|
-
def configure(options = {})
|
45
|
-
if block_given?
|
46
|
-
yield config
|
47
|
-
else
|
48
|
-
options.each do |key, val|
|
49
|
-
config.send("#{key}=", val)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def namespace
|
55
|
-
@namespace ||= connection { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
|
56
|
-
end
|
57
|
-
|
58
|
-
# Attempt to constantize a string worker_class argument, always
|
59
|
-
# failing back to the original argument when the constant can't be found
|
60
|
-
#
|
61
|
-
# raises an error for other errors
|
62
|
-
def worker_class_constantize(worker_class)
|
63
|
-
return worker_class unless worker_class.is_a?(String)
|
64
|
-
Object.const_get(worker_class)
|
65
|
-
rescue NameError => ex
|
66
|
-
case ex.message
|
67
|
-
when /uninitialized constant/
|
68
|
-
worker_class
|
69
|
-
else
|
70
|
-
raise
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def mocked?
|
75
|
-
config.redis_test_mode == :mock
|
76
|
-
end
|
77
|
-
|
78
|
-
def redis_version
|
79
|
-
@redis_version ||= connection { |conn| conn.info('server')['redis_version'] }
|
80
|
-
end
|
81
|
-
|
82
|
-
def connection(redis_pool = nil)
|
83
|
-
if redis_pool
|
84
|
-
redis_pool.with { |conn| yield conn }
|
85
|
-
else
|
86
|
-
Sidekiq.redis { |conn| yield conn }
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def synchronize(item, redis_pool)
|
91
|
-
Lock::WhileExecuting.synchronize(item, redis_pool) { yield }
|
92
|
-
end
|
93
|
-
end
|
3
|
+
require 'sidekiq_unique_jobs'
|