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.

Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +17 -9
  3. data/.gitignore +1 -3
  4. data/.reek +105 -0
  5. data/.rubocop.yml +36 -1
  6. data/.simplecov +7 -2
  7. data/.travis.yml +11 -10
  8. data/Appraisals +3 -7
  9. data/CHANGELOG.md +17 -0
  10. data/Gemfile +16 -13
  11. data/Guardfile +55 -0
  12. data/README.md +85 -73
  13. data/examples/another_unique_job.rb +13 -0
  14. data/examples/custom_queue_job.rb +12 -0
  15. data/examples/custom_queue_job_with_filter_method.rb +13 -0
  16. data/examples/custom_queue_job_with_filter_proc.rb +16 -0
  17. data/examples/expiring_job.rb +12 -0
  18. data/examples/inline_worker.rb +12 -0
  19. data/examples/just_a_worker.rb +13 -0
  20. data/examples/long_running_job.rb +12 -0
  21. data/examples/main_job.rb +13 -0
  22. data/examples/my_job.rb +12 -0
  23. data/examples/my_unique_job.rb +16 -0
  24. data/examples/my_unique_job_with_filter_method.rb +21 -0
  25. data/examples/my_unique_job_with_filter_proc.rb +19 -0
  26. data/examples/notify_worker.rb +14 -0
  27. data/examples/plain_class.rb +13 -0
  28. data/examples/simple_worker.rb +15 -0
  29. data/examples/spawn_simple_worker.rb +12 -0
  30. data/examples/test_class.rb +9 -0
  31. data/examples/unique_across_workers_job.rb +20 -0
  32. data/examples/unique_job_with_conditional_parameter.rb +18 -0
  33. data/examples/unique_job_with_filter_method.rb +18 -0
  34. data/examples/unique_job_with_nil_unique_args.rb +20 -0
  35. data/examples/unique_job_with_no_unique_args_method.rb +16 -0
  36. data/examples/unique_job_withthout_unique_args_parameter.rb +18 -0
  37. data/examples/unique_on_all_queues_job.rb +16 -0
  38. data/examples/until_and_while_executing_job.rb +13 -0
  39. data/examples/until_executed_2_job.rb +24 -0
  40. data/examples/until_executed_job.rb +25 -0
  41. data/examples/until_executing_job.rb +11 -0
  42. data/examples/until_expired_job.rb +12 -0
  43. data/examples/until_global_expired_job.rb +12 -0
  44. data/examples/while_executing_job.rb +15 -0
  45. data/examples/while_executing_reject_job.rb +14 -0
  46. data/examples/without_argument_job.rb +13 -0
  47. data/lib/sidekiq-unique-jobs.rb +1 -91
  48. data/lib/sidekiq/simulator.rb +15 -16
  49. data/lib/sidekiq_unique_jobs.rb +79 -0
  50. data/lib/sidekiq_unique_jobs/cli.rb +9 -18
  51. data/lib/sidekiq_unique_jobs/client/middleware.rb +16 -18
  52. data/lib/sidekiq_unique_jobs/connection.rb +18 -0
  53. data/lib/sidekiq_unique_jobs/constants.rb +13 -17
  54. data/lib/sidekiq_unique_jobs/core_ext.rb +28 -55
  55. data/lib/sidekiq_unique_jobs/exceptions.rb +30 -0
  56. data/lib/sidekiq_unique_jobs/lock/base_lock.rb +84 -0
  57. data/lib/sidekiq_unique_jobs/lock/until_and_while_executing.rb +11 -6
  58. data/lib/sidekiq_unique_jobs/lock/until_executed.rb +6 -58
  59. data/lib/sidekiq_unique_jobs/lock/until_executing.rb +6 -5
  60. data/lib/sidekiq_unique_jobs/lock/until_expired.rb +17 -0
  61. data/lib/sidekiq_unique_jobs/lock/while_executing.rb +20 -34
  62. data/lib/sidekiq_unique_jobs/lock/while_executing_reject.rb +78 -0
  63. data/lib/sidekiq_unique_jobs/lock/while_executing_requeue.rb +20 -0
  64. data/lib/sidekiq_unique_jobs/locksmith.rb +149 -0
  65. data/lib/sidekiq_unique_jobs/logging.rb +30 -0
  66. data/lib/sidekiq_unique_jobs/options_with_fallback.rb +27 -41
  67. data/lib/sidekiq_unique_jobs/scripts.rb +25 -24
  68. data/lib/sidekiq_unique_jobs/server/middleware.rb +12 -20
  69. data/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb +5 -5
  70. data/lib/sidekiq_unique_jobs/sidekiq_worker_methods.rb +42 -0
  71. data/lib/sidekiq_unique_jobs/testing.rb +40 -50
  72. data/lib/sidekiq_unique_jobs/timeout.rb +15 -0
  73. data/lib/sidekiq_unique_jobs/timeout/calculator.rb +49 -0
  74. data/lib/sidekiq_unique_jobs/unique_args.rb +33 -77
  75. data/lib/sidekiq_unique_jobs/unlockable.rb +5 -14
  76. data/lib/sidekiq_unique_jobs/util.rb +28 -90
  77. data/lib/sidekiq_unique_jobs/version.rb +1 -1
  78. data/redis/acquire_lock.lua +5 -3
  79. data/redis/create.lua +58 -0
  80. data/redis/delete.lua +11 -0
  81. data/redis/release_stale_locks.lua +90 -0
  82. data/redis/signal.lua +21 -0
  83. data/sidekiq-unique-jobs.gemspec +15 -8
  84. metadata +108 -32
  85. data/lib/sidekiq_unique_jobs/config.rb +0 -17
  86. data/lib/sidekiq_unique_jobs/lock.rb +0 -12
  87. data/lib/sidekiq_unique_jobs/lock/until_timeout.rb +0 -17
  88. data/lib/sidekiq_unique_jobs/run_lock_failed.rb +0 -3
  89. data/lib/sidekiq_unique_jobs/script_mock.rb +0 -66
  90. data/lib/sidekiq_unique_jobs/scripts/acquire_lock.rb +0 -47
  91. data/lib/sidekiq_unique_jobs/scripts/release_lock.rb +0 -49
  92. data/lib/sidekiq_unique_jobs/testing/sidekiq_overrides.rb +0 -50
  93. data/lib/sidekiq_unique_jobs/timeout_calculator.rb +0 -67
  94. data/redis/synchronize.lua +0 -16
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class NotifyWorker
6
+ include Sidekiq::Worker
7
+
8
+ sidekiq_options queue: :notify_worker,
9
+ unique: :until_executed
10
+
11
+ def perform(pid, blob)
12
+ [pid, blob]
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class PlainClass
6
+ def self.run(one)
7
+ [one]
8
+ end
9
+
10
+ def run(one)
11
+ [one]
12
+ end
13
+ end
@@ -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,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class SpawnSimpleWorker
6
+ include Sidekiq::Worker
7
+ sidekiq_options queue: :not_default
8
+
9
+ def perform(arg)
10
+ SimpleWorker.perform_async arg
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class TestClass
6
+ def self.run(one)
7
+ one
8
+ end
9
+ 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,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class UntilAndWhileExecutingJob
6
+ include Sidekiq::Worker
7
+
8
+ sidekiq_options queue: :working, unique: :until_and_while_executing, lock_timeout: 0
9
+
10
+ def perform(one)
11
+ [one]
12
+ end
13
+ 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
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class UntilExecutingJob
6
+ include Sidekiq::Worker
7
+
8
+ sidekiq_options queue: :working, unique: :until_executing
9
+
10
+ def perform; end
11
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class UntilExpiredJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options unique: :until_expired, lock_expiration: 1, lock_timeout: 0
8
+
9
+ def perform(one)
10
+ TestClass.run(one)
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class UntilGlobalExpiredJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options unique: :until_expired
8
+
9
+ def perform(arg)
10
+ TestClass.run(arg)
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class WhileExecutingJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options backtrace: 10,
8
+ queue: :working,
9
+ retry: 1,
10
+ unique: :while_executing
11
+
12
+ def perform(args)
13
+ [args]
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class WhileExecutingRejectJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options queue: :rejecting,
8
+ unique: :while_executing_reject
9
+
10
+ def perform(args)
11
+ sleep 5
12
+ p args
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class WithoutArgumentJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options unique: :until_executed,
8
+ log_duplicate_payload: true
9
+
10
+ def perform
11
+ sleep 20
12
+ end
13
+ end
@@ -1,93 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yaml' if RUBY_VERSION.include?('2.0.0')
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'