sidekiq-unique-jobs 7.0.0.beta29 → 7.0.4

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +138 -36
  3. data/README.md +169 -37
  4. data/lib/sidekiq-unique-jobs.rb +0 -2
  5. data/lib/sidekiq_unique_jobs.rb +4 -1
  6. data/lib/sidekiq_unique_jobs/batch_delete.rb +1 -1
  7. data/lib/sidekiq_unique_jobs/changelog.rb +11 -4
  8. data/lib/sidekiq_unique_jobs/constants.rb +1 -0
  9. data/lib/sidekiq_unique_jobs/digests.rb +1 -1
  10. data/lib/sidekiq_unique_jobs/json.rb +7 -1
  11. data/lib/sidekiq_unique_jobs/lock.rb +31 -1
  12. data/lib/sidekiq_unique_jobs/lock_config.rb +2 -0
  13. data/lib/sidekiq_unique_jobs/lua/lock.lua +10 -11
  14. data/lib/sidekiq_unique_jobs/lua/reap_orphans.lua +8 -7
  15. data/lib/sidekiq_unique_jobs/lua/shared/_find_digest_in_process_set.lua +9 -2
  16. data/lib/sidekiq_unique_jobs/middleware.rb +0 -57
  17. data/lib/sidekiq_unique_jobs/on_conflict/replace.rb +9 -8
  18. data/lib/sidekiq_unique_jobs/on_conflict/reschedule.rb +1 -1
  19. data/lib/sidekiq_unique_jobs/orphans/lua_reaper.rb +1 -1
  20. data/lib/sidekiq_unique_jobs/orphans/manager.rb +13 -3
  21. data/lib/sidekiq_unique_jobs/orphans/reaper.rb +10 -0
  22. data/lib/sidekiq_unique_jobs/orphans/ruby_reaper.rb +14 -5
  23. data/lib/sidekiq_unique_jobs/redis/entity.rb +9 -3
  24. data/lib/sidekiq_unique_jobs/redis/sorted_set.rb +27 -0
  25. data/lib/sidekiq_unique_jobs/server.rb +48 -0
  26. data/lib/sidekiq_unique_jobs/timer_task.rb +78 -0
  27. data/lib/sidekiq_unique_jobs/version.rb +1 -1
  28. data/lib/sidekiq_unique_jobs/web.rb +28 -4
  29. data/lib/sidekiq_unique_jobs/web/helpers.rb +24 -3
  30. data/lib/sidekiq_unique_jobs/web/views/changelogs.erb +54 -0
  31. data/lib/sidekiq_unique_jobs/web/views/locks.erb +1 -1
  32. metadata +13 -8
  33. data/lib/sidekiq_unique_jobs/profiler.rb +0 -55
data/README.md CHANGED
@@ -3,9 +3,12 @@
3
3
  <!-- MarkdownTOC -->
4
4
 
5
5
  - [Introduction](#introduction)
6
- - [Requirements](#requirements)
7
- - [Installation](#installation)
6
+ - [Usage](#usage)
7
+ - [Installation](#installation)
8
+ - [Add the middleware](#add-the-middleware)
9
+ - [Your first worker](#your-first-worker)
8
10
  - [Support Me](#support-me)
11
+ - [Requirements](#requirements)
9
12
  - [General Information](#general-information)
10
13
  - [Global Configuration](#global-configuration)
11
14
  - [debug_lua](#debug_lua)
@@ -21,6 +24,8 @@
21
24
  - [lock_prefix](#lock_prefix)
22
25
  - [lock_info](#lock_info)
23
26
  - [Worker Configuration](#worker-configuration)
27
+ - [lock_info](#lock_info-1)
28
+ - [lock_prefix](#lock_prefix-1)
24
29
  - [lock_ttl](#lock_ttl-1)
25
30
  - [lock_timeout](#lock_timeout-1)
26
31
  - [unique_across_queues](#unique_across_queues)
@@ -39,13 +44,15 @@
39
44
  - [replace](#replace)
40
45
  - [Reschedule](#reschedule)
41
46
  - [Custom Strategies](#custom-strategies)
42
- - [Usage](#usage)
47
+ - [Usage](#usage-1)
43
48
  - [Finer Control over Uniqueness](#finer-control-over-uniqueness)
44
49
  - [After Unlock Callback](#after-unlock-callback)
45
50
  - [Logging](#logging)
46
51
  - [Cleanup Dead Locks](#cleanup-dead-locks)
47
52
  - [Other Sidekiq gems](#other-sidekiq-gems)
53
+ - [apartment-sidekiq](#apartment-sidekiq)
48
54
  - [sidekiq-global_id](#sidekiq-global_id)
55
+ - [sidekiq-status](#sidekiq-status)
49
56
  - [Debugging](#debugging)
50
57
  - [Sidekiq Web](#sidekiq-web)
51
58
  - [Show Locks](#show-locks)
@@ -61,7 +68,7 @@
61
68
 
62
69
  ## Introduction
63
70
 
64
- This gem adds unique constraints to the sidekiq queues. The uniqueness is achieved by acquiring locks for a hash of a queue name, a worker class, and job's arguments. Only one lock for a given hash can be acquired. What happens when a lock can't be acquired is governed by a chosen strategy.
71
+ This gem adds unique constraints to the sidekiq queues. The uniqueness is achieved by acquiring locks for a hash of a queue name, a worker class, and job's arguments. By default, only one lock for a given hash can be acquired. What happens when a lock can't be acquired is governed by a chosen `on_conflict`strategy.
65
72
 
66
73
  This is the documentation for the master branch. You can find the documentation for each release by navigating to its tag.
67
74
 
@@ -71,20 +78,9 @@ Here are links to some of the old versions
71
78
  - [v5.0.10](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v5.0.10)
72
79
  - [v4.0.18](https://github.com/mhenrixon/sidekiq-unique-jobs/tree/v4.0.18)
73
80
 
74
- ## Requirements
75
-
76
- - Sidekiq `>= 4.0` (`>= 5.2` recommended)
77
- - Ruby:
78
- - MRI `>= 2.3` (`>= 2.5` recommended)
79
- - JRuby `>= 9.0` (`>= 9.2` recommended)
80
- - Truffleruby
81
- - Redis Server `>= 3.0.2` (`>= 3.2` recommended)
82
- - [ActiveJob officially not supported][48]
83
- - [redis-namespace officially not supported][49]
84
-
85
- See [Sidekiq requirements][24] for detailed requirements of Sidekiq itself (be sure to check the right sidekiq version).
81
+ ## Usage
86
82
 
87
- ## Installation
83
+ ### Installation
88
84
 
89
85
  Add this line to your application's Gemfile:
90
86
 
@@ -98,16 +94,83 @@ And then execute:
98
94
  bundle
99
95
  ```
100
96
 
101
- Or install it yourself as:
97
+ ### Add the middleware
102
98
 
103
- ```bash
104
- gem install sidekiq-unique-jobs
99
+ Before v7, the middleware was configured automatically. Since some people reported issues with other gems (see [Other Sidekiq Gems](#other-sidekiq-gems)) it was decided to give full control over to the user.
100
+
101
+ *NOTE* if you want to use the reaper you also need to configure the server middleware.
102
+
103
+ [A full example](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/myapp/config/initializers/sidekiq.rb#L12)
104
+
105
+ ```ruby
106
+ Sidekiq.configure_server do |config|
107
+ config.redis = { url: ENV["REDIS_URL"], driver: :hiredis }
108
+
109
+ config.client_middleware do |chain|
110
+ chain.add SidekiqUniqueJobs::Middleware::Client
111
+ end
112
+
113
+ config.server_middleware do |chain|
114
+ chain.add SidekiqUniqueJobs::Middleware::Server
115
+ end
116
+
117
+ SidekiqUniqueJobs::Server.configure(config)
118
+ end
119
+
120
+ Sidekiq.configure_client do |config|
121
+ config.redis = { url: ENV["REDIS_URL"], driver: :hiredis }
122
+
123
+ config.client_middleware do |chain|
124
+ chain.add SidekiqUniqueJobs::Middleware::Client
125
+ end
126
+ end
105
127
  ```
106
128
 
129
+ ### Your first worker
130
+
131
+ ```ruby
132
+ # frozen_string_literal: true
133
+
134
+ class UntilExecutedWorker
135
+ include Sidekiq::Worker
136
+
137
+ sidekiq_options queue: :special,
138
+ retry: false,
139
+ lock: :until_executed,
140
+ lock_info: true,
141
+ lock_timeout: 0,
142
+ lock_prefix: "special",
143
+ lock_ttl: 0,
144
+ lock_limit: 5
145
+
146
+ def perform
147
+ logger.info("cowboy")
148
+ sleep(1) # hardcore processing
149
+ logger.info("beebop")
150
+ end
151
+ end
152
+
153
+ ```
154
+
155
+ You can read more about the worker configuration in [Worker Configuration](#worker-configuration) below.
156
+
107
157
  ## Support Me
108
158
 
109
159
  Want to show me some ❤️ for the hard work I do on this gem? You can use the following PayPal link: [https://paypal.me/mhenrixon1](https://paypal.me/mhenrixon1). Any amount is welcome and let me tell you it feels good to be appreciated. Even a dollar makes me super excited about all of this.
110
160
 
161
+ ## Requirements
162
+
163
+ - Sidekiq `>= 5.0` (`>= 5.2` recommended)
164
+ - Ruby:
165
+ - MRI `>= 2.5` (`>= 2.6` recommended)
166
+ - JRuby `>= 9.0` (`>= 9.2` recommended)
167
+ - Truffleruby
168
+ - Redis Server `>= 3.2` (`>= 5.0` recommended)
169
+ - [ActiveJob officially not supported][48]
170
+ - [redis-namespace officially not supported][49]
171
+
172
+ See [Sidekiq requirements][24] for detailed requirements of Sidekiq itself (be sure to check the right sidekiq version).
173
+
111
174
  ## General Information
112
175
 
113
176
  See [Interaction w/ Sidekiq](https://github.com/mhenrixon/sidekiq-unique-jobs/wiki/How-this-gem-interacts-with-Sidekiq) on how the gem interacts with Sidekiq.
@@ -122,16 +185,16 @@ Configure SidekiqUniqueJobs in an initializer or the sidekiq initializer on appl
122
185
 
123
186
  ```ruby
124
187
  SidekiqUniqueJobs.configure do |config|
125
- config.debug_lua = true
126
- config.lock_info = true
127
- config.lock_ttl = 10.minutes
128
- config.lock_timeout = 10.minutes
129
- config.logger = Sidekiq.logger
130
- config.max_history = 10_000
131
- config.reaper = :lua
132
- config.reaper_count = 100
133
- config.reaper_interval = 10
134
- config.reaper_timeout = 5
188
+ config.logger = Sidekiq.logger # default, change at your own discretion
189
+ config.debug_lua = false # Turn on when debugging
190
+ config.lock_info = false # Turn on when debugging
191
+ config.lock_ttl = 600 # Expire locks after 10 minutes
192
+ config.lock_timeout = nil # turn off lock timeout
193
+ config.max_history = 0 # Turn on when debugging
194
+ config.reaper = :ruby # :ruby, :lua or :none/nil
195
+ config.reaper_count = 1000 # Stop reaping after this many keys
196
+ config.reaper_interval = 600 # Reap orphans every 10 minutes
197
+ config.reaper_timeout = 150 # Timeout reaper after 2.5 minutes
135
198
  end
136
199
  ```
137
200
 
@@ -253,11 +316,27 @@ Using lock info will create an additional key for the lock with a json object co
253
316
 
254
317
  ## Worker Configuration
255
318
 
319
+ ### lock_info
320
+
321
+ Lock info gathers information about a specific lock. It collects things like which `lock_args` where used to compute the `lock_digest` that is used for maintaining uniqueness.
322
+
323
+ ```ruby
324
+ sidekiq_options lock_info: false # this is the default, set to true to turn on
325
+ ```
326
+
327
+ ### lock_prefix
328
+
329
+ Use if you want a different key prefix for the keys in redis.
330
+
331
+ ```ruby
332
+ sidekiq_options lock_prefix: "uniquejobs" # this is the default value
333
+ ```
334
+
256
335
  ### lock_ttl
257
336
 
258
337
  Lock TTL decides how long to wait after the job has been successfully processed before making it possible to reuse that lock.
259
338
 
260
- Since `v6.0.11` the other locks will expire after the server is done processing.
339
+ Starting from `v7` the expiration will take place when the job is pushed to the queue.
261
340
 
262
341
  ```ruby
263
342
  sidekiq_options lock_ttl: nil # default - don't expire keys
@@ -278,6 +357,8 @@ sidekiq_options lock_timeout: nil # lock indefinitely, this process won't contin
278
357
 
279
358
  This configuration option is slightly misleading. It doesn't disregard the queue on other jobs. Just on itself, this means that a worker that might schedule jobs into multiple queues will be able to have uniqueness enforced on all queues it is pushed to.
280
359
 
360
+ This is mainly intended for `Worker.set(queue: :another).perform_async`.
361
+
281
362
  ```ruby
282
363
  class Worker
283
364
  include Sidekiq::Worker
@@ -428,7 +509,7 @@ The last one is log which can be be used with the lock `UntilExecuted` and `Unti
428
509
  It is possible for locks to have different conflict strategy for the client and server. This is useful for `:until_and_while_executing`.
429
510
 
430
511
  ```ruby
431
- sidekiq_options lock: :until_and_while_executing,
512
+ sidekiq_options lock: :until_and_while_executing,
432
513
  on_conflict: { client: :log, server: :reject }
433
514
  ```
434
515
 
@@ -628,7 +709,7 @@ class MyWorker
628
709
  end
629
710
  ```
630
711
 
631
- Starting in v5.1, Sidekiq can also fire a global callback when a job dies:
712
+ Starting in v5.1, Sidekiq can also fire a global callback when a job dies: In version 7, this is handled automatically for you. You don't need to add a death handler, if you configure v7 like in [Add the middleware](#add-the-middleware) you don't have to worry about the below.
632
713
 
633
714
  ```ruby
634
715
  Sidekiq.configure_server do |config|
@@ -641,10 +722,30 @@ end
641
722
 
642
723
  ### Other Sidekiq gems
643
724
 
725
+ #### apartment-sidekiq
726
+
727
+ It was reported in [#536](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/536) that the order of the Sidekiq middleware needs to be as follows.
728
+
729
+ ```ruby
730
+ Sidekiq.client_middleware do |chain|
731
+ chain.add Apartment::Sidekiq::Middleware::Client
732
+ chain.add SidekiqUniqueJobs::Middleware::Client
733
+ end
734
+
735
+ Sidekiq.server_middleware do |chain|
736
+ chain.add Apartment::Sidekiq::Middleware::Server
737
+ chain.add SidekiqUniqueJobs::Middleware::Server
738
+ end
739
+ ```
740
+
741
+ The reason being that this gem needs to be configured AFTER the apartment gem or the apartment will not be able to be considered for uniqueness
742
+
644
743
  #### sidekiq-global_id
645
744
 
646
745
  It was reported in [#235](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/235) that the order of the Sidekiq middleware needs to be as follows.
647
746
 
747
+ For a working setup check the following [file](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/myapp/config/sidekiq.rb#L12).
748
+
648
749
  ```ruby
649
750
  Sidekiq.client_middleware do |chain|
650
751
  chain.add Sidekiq::GlobalId::ClientMiddleware
@@ -652,12 +753,44 @@ Sidekiq.client_middleware do |chain|
652
753
  end
653
754
 
654
755
  Sidekiq.server_middleware do |chain|
655
- chain.add SidekiqUniqueJobs::Middleware::Server
656
756
  chain.add Sidekiq::GlobalId::ServerMiddleware
757
+ chain.add SidekiqUniqueJobs::Middleware::Server
758
+ end
759
+ ```
760
+
761
+ The reason for this is that the global id needs to be set before the unique jobs middleware runs. Otherwise that won't be available for uniqueness.
762
+
763
+ #### sidekiq-status
764
+
765
+ It was reported in [#564](https://github.com/mhenrixon/sidekiq-unique-jobs/issues/564) that the order of the middleware needs to be as follows.
766
+
767
+ ```ruby
768
+ # Thanks to @ArturT for the correction
769
+
770
+ Sidekiq.configure_server do |config|
771
+ config.client_middleware do |chain|
772
+ chain.add SidekiqUniqueJobs::Middleware::Client
773
+ chain.add Sidekiq::Status::ClientMiddleware, expiration: 30.minutes
774
+ end
775
+
776
+ config.server_middleware do |chain|
777
+ chain.add Sidekiq::Status::ServerMiddleware, expiration: 30.minutes
778
+ chain.add SidekiqUniqueJobs::Middleware::Server
779
+ end
780
+
781
+ SidekiqUniqueJobs::Server.configure(config)
782
+ end
783
+
784
+
785
+ Sidekiq.configure_client do |config|
786
+ config.client_middleware do |chain|
787
+ chain.add SidekiqUniqueJobs::Middleware::Client
788
+ chain.add Sidekiq::Status::ClientMiddleware, expiration: 30.minutes
789
+ end
657
790
  end
658
791
  ```
659
792
 
660
- For a working setup check the following [file](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/945c4c4c517168d49e3f8ee952fcc9c430865635/myapp/config/initializers/sidekiq.rb#L8)
793
+ The reason for this is that if a job is duplicated it shouldn't end up with the status middleware at all. Status is just a monitor so to prevent clashes, leftovers and ensure cleanup. The status middleware should run after uniqueness on client and before on server. This will lead to less surprises.
661
794
 
662
795
  ## Debugging
663
796
 
@@ -728,7 +861,6 @@ If you are not using RSpec (a lot of people prefer minitest or test unit) you ca
728
861
  assert SidekiqUniqueJobs.validate_worker!(BadWorker.get_sidekiq_options)
729
862
  ```
730
863
 
731
-
732
864
  ### Uniqueness
733
865
 
734
866
  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: [Enterprise unique jobs][]
@@ -771,7 +903,7 @@ RSpec.describe Workers::CoolOne do
771
903
  end
772
904
  ```
773
905
 
774
- It is recommened to leave the uniqueness testing to the gem maintainers. If you care about how the gem is integration tested have a look at the following specs:
906
+ It is recommended to leave the uniqueness testing to the gem maintainers. If you care about how the gem is integration tested have a look at the following specs:
775
907
 
776
908
  - [spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/integration/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb)
777
909
  - [spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/spec/integration/sidekiq_unique_jobs/lock/until_executed_spec.rb)
@@ -1,5 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "sidekiq_unique_jobs"
4
-
5
- SidekiqUniqueJobs::Middleware.configure
@@ -3,9 +3,10 @@
3
3
  require "brpoplpush/redis_script"
4
4
  require "concurrent/future"
5
5
  require "concurrent/promises"
6
- require "concurrent/timer_task"
7
6
  require "concurrent/map"
8
7
  require "concurrent/mutable_struct"
8
+ require "concurrent/timer_task"
9
+ require "concurrent/executor/ruby_single_thread_executor"
9
10
  require "digest"
10
11
  require "digest/sha1"
11
12
  require "erb"
@@ -14,6 +15,7 @@ require "json"
14
15
  require "pathname"
15
16
  require "sidekiq"
16
17
 
18
+ require "sidekiq_unique_jobs/timer_task"
17
19
  require "sidekiq_unique_jobs/version"
18
20
  require "sidekiq_unique_jobs/version_check"
19
21
  require "sidekiq_unique_jobs/constants"
@@ -71,3 +73,4 @@ require "sidekiq_unique_jobs/config"
71
73
  require "sidekiq_unique_jobs/sidekiq_unique_jobs"
72
74
  require "sidekiq_unique_jobs/update_version"
73
75
  require "sidekiq_unique_jobs/upgrade_locks"
76
+ require "sidekiq_unique_jobs/server"
@@ -44,7 +44,7 @@ module SidekiqUniqueJobs
44
44
  #
45
45
  # @return [void]
46
46
  #
47
- def self.call(digests, conn)
47
+ def self.call(digests, conn = nil)
48
48
  new(digests, conn).call
49
49
  end
50
50
 
@@ -7,6 +7,13 @@ module SidekiqUniqueJobs
7
7
  # @author Mikael Henriksson <mikael@mhenrixon.com>
8
8
  #
9
9
  class Changelog < Redis::SortedSet
10
+ #
11
+ # @return [Integer] the number of matches to return by default
12
+ DEFAULT_COUNT = 1_000
13
+ #
14
+ # @return [String] the default pattern to use for matching
15
+ SCAN_PATTERN = "*"
16
+
10
17
  def initialize
11
18
  super(CHANGELOGS)
12
19
  end
@@ -34,10 +41,10 @@ module SidekiqUniqueJobs
34
41
  #
35
42
  # @return [Array<Hash>] an array of entries
36
43
  #
37
- def entries(pattern: "*", count: nil)
44
+ def entries(pattern: SCAN_PATTERN, count: DEFAULT_COUNT)
38
45
  options = {}
39
- options[:match] = pattern if pattern
40
- options[:count] = count if count
46
+ options[:match] = pattern
47
+ options[:count] = count
41
48
 
42
49
  redis do |conn|
43
50
  conn.zscan_each(key, **options).to_a.map { |entry| load_json(entry[0]) }
@@ -53,7 +60,7 @@ module SidekiqUniqueJobs
53
60
  #
54
61
  # @return [Array<Integer, Integer, Array<Hash>] the total size, next cursor and changelog entries
55
62
  #
56
- def page(cursor, pattern: "*", page_size: 100)
63
+ def page(cursor: 0, pattern: "*", page_size: 100)
57
64
  redis do |conn|
58
65
  total_size, result = conn.multi do
59
66
  conn.zcard(key)
@@ -11,6 +11,7 @@ module SidekiqUniqueJobs
11
11
  AT ||= "at"
12
12
  CHANGELOGS ||= "uniquejobs:changelog"
13
13
  CLASS ||= "class"
14
+ CREATED_AT ||= "created_at"
14
15
  DEAD_VERSION ||= "uniquejobs:dead"
15
16
  DIGESTS ||= "uniquejobs:digests"
16
17
  ERRORS ||= "errors"
@@ -78,7 +78,7 @@ module SidekiqUniqueJobs
78
78
  def entries(pattern: SCAN_PATTERN, count: DEFAULT_COUNT)
79
79
  options = {}
80
80
  options[:match] = pattern
81
- options[:count] = count if count
81
+ options[:count] = count
82
82
 
83
83
  result = redis { |conn| conn.zscan_each(key, **options).to_a }
84
84
 
@@ -15,11 +15,17 @@ module SidekiqUniqueJobs
15
15
  # @return [Object]
16
16
  #
17
17
  def load_json(string)
18
- return unless string && !string.empty?
18
+ return if string.nil? || string.empty?
19
19
 
20
20
  ::JSON.parse(string)
21
21
  end
22
22
 
23
+ def safe_load_json(string)
24
+ return string if string.is_a?(Hash)
25
+
26
+ load_json(string)
27
+ end
28
+
23
29
  #
24
30
  # Dumps an object into a JSON string
25
31
  #
@@ -53,7 +53,7 @@ module SidekiqUniqueJobs
53
53
  #
54
54
  # Locks a job_id
55
55
  #
56
- # @note intended only for testing purposez
56
+ # @note intended only for testing purposes
57
57
  #
58
58
  # @param [String] job_id a sidekiq JID
59
59
  # @param [Hash] lock_info information about the lock
@@ -73,6 +73,36 @@ module SidekiqUniqueJobs
73
73
  end
74
74
  end
75
75
 
76
+ #
77
+ # Create the :QUEUED key
78
+ #
79
+ # @note intended only for testing purposes
80
+ #
81
+ # @param [String] job_id a sidekiq JID
82
+ #
83
+ # @return [void]
84
+ #
85
+ def queue(job_id)
86
+ redis do |conn|
87
+ conn.lpush(key.queued, job_id)
88
+ end
89
+ end
90
+
91
+ #
92
+ # Create the :PRIMED key
93
+ #
94
+ # @note intended only for testing purposes
95
+ #
96
+ # @param [String] job_id a sidekiq JID
97
+ #
98
+ # @return [void]
99
+ #
100
+ def prime(job_id)
101
+ redis do |conn|
102
+ conn.lpush(key.primed, job_id)
103
+ end
104
+ end
105
+
76
106
  #
77
107
  # Unlock a specific job_id
78
108
  #