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
data/README.md CHANGED
@@ -2,15 +2,28 @@
2
2
 
3
3
  The missing unique jobs for sidekiq
4
4
 
5
- ## Requirements
5
+ # Documentation
6
+
7
+ This is the documentation for the master branch. You can find the documentation for each release by navigating to its tag: https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10.
6
8
 
9
+ Below are links to the latest major versions (4 & 5):
10
+ - [v5.0.10](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10)
11
+ - [v4.0.18](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.18)
7
12
 
8
- See https://github.com/mperham/sidekiq#requirements for what is required. Starting from 5.0.0 only sidekiq >= 4 is supported and support for MRI <= 2.1 is dropped.
13
+ ## Requirements
9
14
 
10
- ### Version 4 Upgrade instructions
15
+ See https://github.com/mperham/sidekiq#requirements for what is required. Starting from 5.0.0 only sidekiq >= 4 is supported and support for MRI <= 2.1 is dropped. ActiveJob is not supported
11
16
 
12
17
  Version 5 requires redis >= 3
13
18
 
19
+ ### ActiveJob
20
+
21
+ Due to the simplicity of ActiveJob and the complexity of this game there is no officially supported way of doing ActiveJob. If you want to use uniqueness you should be using sidekiq directly. I know some projects started by using ActiveJob out of ignorance and someone has to do a whole lot of work to migrate the workers to use sidekiq directly...
22
+
23
+ If you are in this position and you can't figure it out; I have done such migrations for really big clients before. I am a consultant with a ton of experience on such jobs. My rate is fair and I am easy to get along with.
24
+
25
+ If that is not an option I apologize. This gem won't support ActiveJob moving forward. It would require monkey patching too much.
26
+
14
27
  ## Installation
15
28
 
16
29
  Add this line to your application's Gemfile:
@@ -27,85 +40,107 @@ Or install it yourself as:
27
40
 
28
41
  ## Locking
29
42
 
30
- Like @mperham mentions on [this wiki page](https://github.com/mperham/sidekiq/wiki/Related-Projects#unique-jobs) it is hard to enforce uniqueness with redis in a distributed redis setting.
43
+ Sidekiq consists of a client and a server. The client is responsible for pushing jobs to the queue and the server is responsible for actually processing the jobs. When the client puts the job to the queue the middleware checks for uniqueness and creates a lock. When the server then processes the job that lock is released.
31
44
 
32
- To make things worse there are many ways of wanting to enforce uniqueness.
45
+ ### Options
33
46
 
34
- ### While Executing
47
+ #### Lock Expiration
35
48
 
36
- Due to discoverability of the different lock types `unique` sidekiq option it was decided to use the `while_executing` as a default. Most people will note that scheduling any number of jobs with the same arguments is possible.
49
+ This is probably not the configuration option you want...
37
50
 
38
- ```ruby
39
- sidekiq_options unique: :while_executing
40
- ```
51
+ Since the client and the server are disconnected and not running inside the same process, setting a lock expiration is probably not what you want. Any keys that are used by this gem WILL be removed at the time of the expiration. For jobs that are scheduled in the future the key will expire when that job is scheduled + whatever expiration you have set.
41
52
 
42
- Is to make sure that a job can be scheduled any number of times but only executed a single time per argument provided to the job we call this runtime uniqueness. This is probably most useful for background jobs that are fast to execute. (See mhenrixon/sidekiq-unique-jobs#111 for a great example of when this would be right.) While the job is executing/performing no other jobs can be executed at the same time.
53
+ In previous versions there was a default expiration of 30 minutes which didn't work for a lot of long running jobs. Since version 6 there will be no expiration of any jobs from the default configuration. Please don't use `lock_expiration` unless you really know what you are doing.
43
54
 
44
- The way it currently works is that the jobs can be put on the queue but any succeedent job will wait until the first one finishes.
55
+ ```ruby
56
+ sidekiq_options lock_expiration: nil # default - don't expire keys
57
+ sidekiq_options lock_expiration: 20.days # expire this lock in 20 days
58
+ ```
45
59
 
46
- There is an example of this to try it out in the `rails_example` application. Run `foreman start` in the root of the directory and open the url: `localhost:5000/work/duplicate_while_executing`.
60
+ #### Lock Timeout
47
61
 
48
- In the console you should see something like:
62
+ This is the timeout (how long to wait) when creating the lock. By default we don't use a timeout so we won't wait for the lock to be created. If you want it is possible to set this like below.
49
63
 
50
- ```
51
- 0:32:24 worker.1 | 2017-04-23T08:32:24.955Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: start
52
- 10:32:24 worker.1 | 2017-04-23T08:32:24.956Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: start
53
- 10:32:24 worker.1 | 2017-04-23T08:32:24.957Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: start
54
- 10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: start
55
- 10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 WhileExecutingWorker INFO: perform(1, 2)
56
- 10:32:34 worker.1 | 2017-04-23T08:32:34.964Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: done: 10.009 sec
57
- 10:32:34 worker.1 | 2017-04-23T08:32:34.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 WhileExecutingWorker INFO: perform(1, 2)
58
- 10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 WhileExecutingWorker INFO: perform(1, 2)
59
- 10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: done: 20.009 sec
60
- 10:32:54 worker.1 | 2017-04-23T08:32:54.970Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f WhileExecutingWorker INFO: perform(1, 2)
61
- 10:32:54 worker.1 | 2017-04-23T08:32:54.969Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: done: 30.012 sec
62
- 10:33:04 worker.1 | 2017-04-23T08:33:04.973Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: done: 40.014 sec
64
+ ```ruby
65
+ sidekiq_options lock_timeout: 0 # default - don't wait at all
66
+ sidekiq_options lock_timeout: 5 # wait 5 seconds
67
+ sidekiq_options lock_timeout: nil # lock indefinitely, this process won't continue until it gets a lock. VERY DANGEROUS!!
63
68
  ```
64
69
 
70
+ ####
71
+
65
72
  ### Until Executing
66
73
 
74
+ Locks from when the client pushes the job to the queue. Will be unlocked before the server starts processing the job.
75
+
76
+ **NOTE** this is probably not so good for jobs that shouldn't be running simultaneously (aka slow jobs).
77
+
67
78
  ```ruby
68
79
  sidekiq_options unique: :until_executing
69
80
  ```
70
81
 
71
- This means that a job can only be scheduled into redis once per whatever the configuration of unique arguments. Any jobs added until the first one of the same arguments has been unlocked will just be dropped. This is what was tripping many people up. They would schedule a job to run in the future and it would be impossible to schedule new jobs with those same arguments even immediately. There was some forth and back between also locking jobs on the scheduled queue and the regular queues but in the end I decided it was best to separate these two features out into different locking mechanisms. I think what most people are after is to be able to lock a job while executing or that seems to be what people are most missing at the moment.
72
-
73
82
  ### Until Executed
74
83
 
84
+ Locks from when the client pushes the job to the queue. Will be unlocked when the server has successfully processed the job.
85
+
86
+
75
87
  ```ruby
76
88
  sidekiq_options unique: :until_executed
77
89
  ```
78
90
 
79
- This is the combination of the two above. First we lock the job until it executes, then as the job begins executes we keep the lock so that no other jobs with the same arguments can execute at the same time.
80
-
81
91
  ### Until Timeout
82
92
 
93
+ Locks from when the client pushes the job to the queue. Will be unlocked when the specified timeout has been reached.
94
+
83
95
  ```ruby
84
- sidekiq_options unique: :until_timeout
96
+ sidekiq_options unique: :until_expired
85
97
  ```
86
98
 
87
- The job won't be unlocked until the timeout/expiry runs out.
88
-
89
99
  ### Unique Until And While Executing
90
100
 
101
+ Locks when the client pushes the job to the queue. The queue will be unlocked when the server starts processing the job. The server then goes on to creating a runtime lock for the job to prevent simultaneous jobs from being executed. As soon as the server starts processing a job, the client can push the same job to the queue.
102
+
91
103
  ```ruby
92
104
  sidekiq_options unique: :until_and_while_executing
93
105
  ```
94
106
 
95
- This lock is exactly what you would expect. It is considered unique in a way until executing begins and it is locked while executing so what differs from `UntilExecuted`?
107
+ ### While Executing
96
108
 
97
- The difference is that this job has two types of uniqueness:
98
- 1. It is unique until execution
99
- 2. It is unique while executing
109
+ With this lock type it is possible to put any number of these jobs on the queue, but as the server pops the job from the queue it will create a lock and then wait until other locks are done processing. It *looks* like multiple jobs are running at the same time but in fact the second job will only be waiting for the first job to finish.
100
110
 
101
- That means it locks for any job with the same arguments to be persisted into redis and just like you would expect it will only ever allow one job of the same unique arguments to run at any given time but as soon as the runtime lock has been acquired the schedule/async lock is released.
111
+ #### NOTE:
102
112
 
103
- ### Uniqueness Scope
113
+ Unless this job is configured with a `lock_timeout: nil` or `lock_timeout: > 0` then all jobs that are attempted to be executed will just be dropped without waiting.
114
+
115
+ ```ruby
116
+ sidekiq_options unique: :while_executing, lock_timeout: nil
117
+ ```
104
118
 
119
+ There is an example of this to try it out in the `rails_example` application. Run `foreman start` in the root of the directory and open the url: `localhost:5000/work/duplicate_while_executing`.
120
+
121
+ In the console you should see something like:
122
+
123
+ ```
124
+ 0:32:24 worker.1 | 2017-04-23T08:32:24.955Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: start
125
+ 10:32:24 worker.1 | 2017-04-23T08:32:24.956Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: start
126
+ 10:32:24 worker.1 | 2017-04-23T08:32:24.957Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: start
127
+ 10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: start
128
+ 10:32:24 worker.1 | 2017-04-23T08:32:24.959Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 WhileExecutingWorker INFO: perform(1, 2)
129
+ 10:32:34 worker.1 | 2017-04-23T08:32:34.964Z 84404 TID-ougq4thko WhileExecutingWorker JID-400ec51c9523f41cd4a35058 INFO: done: 10.009 sec
130
+ 10:32:34 worker.1 | 2017-04-23T08:32:34.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 WhileExecutingWorker INFO: perform(1, 2)
131
+ 10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 WhileExecutingWorker INFO: perform(1, 2)
132
+ 10:32:44 worker.1 | 2017-04-23T08:32:44.965Z 84404 TID-ougq8csew WhileExecutingWorker JID-8d6d9168368eedaed7f75763 INFO: done: 20.009 sec
133
+ 10:32:54 worker.1 | 2017-04-23T08:32:54.970Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f WhileExecutingWorker INFO: perform(1, 2)
134
+ 10:32:54 worker.1 | 2017-04-23T08:32:54.969Z 84404 TID-ougq8crt8 WhileExecutingWorker JID-affcd079094c9b26e8b9ba60 INFO: done: 30.012 sec
135
+ 10:33:04 worker.1 | 2017-04-23T08:33:04.973Z 84404 TID-ougq8cs8s WhileExecutingWorker JID-9e197460c067b22eb1b5d07f INFO: done: 40.014 sec
136
+ ```
137
+
138
+
139
+ ### Uniqueness Scope
105
140
 
106
141
  - Queue specific locks
107
- - Across all queues - [spec/jobs/unique_on_all_queues_job.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/jobs/unique_on_all_queues_job.rb)
108
- - Across all workers - [spec/jobs/unique_across_workers_job.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/jobs/unique_across_workers_job.rb)
142
+ - Across all queues - [examples/unique_on_all_queues_job.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/examples/unique_on_all_queues_job.rb)
143
+ - Across all workers - [examples/unique_across_workers_job.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/examples/unique_across_workers_job.rb)
109
144
  - Timed / Scheduled jobs
110
145
 
111
146
  ## Usage
@@ -121,32 +156,22 @@ should be unique. The job will be unique for the number of seconds configured (d
121
156
  or until the job has been completed. Thus, the job will be unique for the shorter of the two. Note that Sidekiq versions before 3.0 will remove job keys after an hour, which means jobs can remain unique for at most an hour.
122
157
 
123
158
  If you want the unique job to stick around even after it has been successfully
124
- processed then just set `unique: :until_timeout`.
159
+ processed then just set `unique: :until_expired`.
125
160
 
126
- You can also control the expiration length of the uniqueness check. If you want to enforce uniqueness over a longer period than the default of 30 minutes then you can pass the number of seconds you want to use to the sidekiq options:
161
+ You can also control the `lock_expiration` of the uniqueness check. If you want to enforce uniqueness over a longer period than the default of 30 minutes then you can pass the number of seconds you want to use to the sidekiq options:
127
162
 
128
163
  ```ruby
129
- sidekiq_options unique: :until_timeout, unique_expiration: 120 * 60 # 2 hours
164
+ sidekiq_options unique: :until_expired, lock_expiration: 120 * 60 # 2 hours
130
165
  ```
131
166
 
132
167
  For locking modes (`:while_executing` and `:until_and_while_executing`) you can control the expiration length of the runtime uniqueness. If you want to enforce uniqueness over a longer period than the default of 60 seconds, then you can pass the number of seconds you want to use to the sidekiq options:
133
168
 
134
169
  ```ruby
135
- sidekiq_options unique: :while_executing, run_lock_expiration: 2 * 60 # 2 minutes
170
+ sidekiq_options unique: :while_executing, lock_expiration: 2 * 60 # 2 minutes
136
171
  ```
137
172
 
138
173
  Requiring the gem in your gemfile should be sufficient to enable unique jobs.
139
174
 
140
- ### Usage with ActiveJob
141
-
142
- ```ruby
143
- Sidekiq.default_worker_options = {
144
- unique: :until_executing,
145
- unique_args: ->(args) { [ args.first.except('job_id') ] }
146
- }
147
- ```
148
-
149
-
150
175
  ### Finer Control over Uniqueness
151
176
 
152
177
  Sometimes it is desired to have a finer control over which arguments are used in determining uniqueness of the job, and others may be _transient_. For this use-case, you need to define either a `unique_args` method, or a ruby proc.
@@ -246,9 +271,6 @@ Start the console with the following command `bundle exec jobs console`.
246
271
  #### Remove Unique Keys
247
272
  `del '*', 100, false` the dry_run and count parameters are both required. This is to have some type of protection against clearing out all uniqueness.
248
273
 
249
- #### Expire
250
- `expire` clears the unique hash from expired keys
251
-
252
274
  ### Command Line
253
275
 
254
276
  `bundle exec jobs` displays help on how to use the unique jobs command line.
@@ -259,23 +281,13 @@ There is a [![Join the chat at https://gitter.im/mhenrixon/sidekiq-unique-jobs](
259
281
 
260
282
  ## Testing
261
283
 
262
- To enable the testing for `sidekiq-unique-jobs`, add `require 'sidekiq_unique_jobs/testing'` to your testing helper.
284
+ This has been probably the most confusing part of this gem. People get really confused with how unreliable the unique jobs have been. I there for decided to do what Mike is doing for sidekiq enterprise. Read the section about unique jobs.
263
285
 
264
- You can if you want use `gem 'mock_redis'` to prevent sidekiq unique jobs using redis.
265
-
266
- See https://github.com/mhenrixon/sidekiq-unique-jobs/tree/master/rails_example/spec/controllers/work_controller_spec.rb for an example of how to configure sidekiq and unique jobs without redis.
267
-
268
- If you really don't care about testing uniquness and trust we get that stuff right you can (in newer sidekiq versions) remove the client middleware.
286
+ https://www.dailydrip.com/topics/sidekiq/drips/sidekiq-enterprise-unique-jobs
269
287
 
270
288
  ```ruby
271
- describe "Some test" do
272
- before(:each) do
273
- Sidekiq.configure_client do |config|
274
- config.client_middleware do |chain|
275
- chain.remove SidekiqUniqueJobs::Client::Middleware
276
- end
277
- end
278
- end
289
+ SidekiqUniqueJobs.configure do |config|
290
+ config.enabled = !Rails.env.test?
279
291
  end
280
292
  ```
281
293
 
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class AnotherUniqueJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options queue: :working2, retry: 1, backtrace: 10,
8
+ unique: :until_executed
9
+
10
+ def perform(args)
11
+ args
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class CustomQueueJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options queue: :customqueue
8
+
9
+ def perform(one, two = 'two')
10
+ [one, two]
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ require_relative 'custom_queue_job'
6
+
7
+ class CustomQueueJobWithFilterMethod < CustomQueueJob
8
+ sidekiq_options unique: :until_executed, unique_args: :args_filter
9
+
10
+ def self.args_filter(args)
11
+ args.first
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ require_relative './custom_queue_job'
6
+
7
+ class CustomQueueJobWithFilterProc < CustomQueueJob
8
+ # slightly contrived example of munging args to the
9
+ # worker and removing a random bit.
10
+ sidekiq_options unique: :until_expired,
11
+ unique_args: (lambda do |args|
12
+ options = args.extract_options!
13
+ options.delete('random')
14
+ args + [options]
15
+ end)
16
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class ExpiringJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options unique: :until_executed, lock_expiration: 10 * 60
8
+
9
+ def perform(one, two)
10
+ [one, two]
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class InlineWorker
6
+ include Sidekiq::Worker
7
+ sidekiq_options unique: :while_executing, lock_timeout: 5
8
+
9
+ def perform(one)
10
+ TestClass.run(one)
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class JustAWorker
6
+ include Sidekiq::Worker
7
+
8
+ sidekiq_options unique: :until_executed, queue: :testqueue
9
+
10
+ def perform(options = {})
11
+ options
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class LongRunningJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options queue: :customqueue, retry: true, unique: :until_and_while_executing,
8
+ lock_expiration: 7_200, retry_count: 10
9
+ def perform(one, two)
10
+ [one, two]
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class MainJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options queue: :customqueue, unique: :until_executed,
8
+ log_duplicate_payload: true
9
+
10
+ def perform(arg)
11
+ [arg]
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class MyJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options queue: :working, retry: 1, backtrace: 10
8
+
9
+ def perform(one)
10
+ [one]
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class MyUniqueJob
6
+ include Sidekiq::Worker
7
+ sidekiq_options queue: :customqueue,
8
+ retry: true,
9
+ retry_count: 10,
10
+ unique: :until_executed,
11
+ lock_expiration: 7_200
12
+
13
+ def perform(one, two)
14
+ [one, two]
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class MyUniqueJobWithFilterMethod
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(*)
14
+ # NO-OP
15
+ end
16
+
17
+ def self.filtered_args(args)
18
+ options = args.extract_options!
19
+ [args.first, options['type']]
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+
5
+ class MyUniqueJobWithFilterProc
6
+ include Sidekiq::Worker
7
+ sidekiq_options queue: :customqueue,
8
+ retry: true,
9
+ backtrace: true,
10
+ unique: :until_executed,
11
+ unique_args: (lambda do |args|
12
+ options = args.extract_options!
13
+ [args.first, options['type']]
14
+ end)
15
+
16
+ def perform(*)
17
+ # NO-OP
18
+ end
19
+ end