sidekiq-middleware 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/CHANGES.md +5 -0
- data/Gemfile +3 -2
- data/README.md +8 -1
- data/lib/sidekiq-middleware.rb +7 -7
- data/lib/sidekiq-middleware/client/unique_jobs.rb +10 -14
- data/lib/sidekiq-middleware/server/unique_jobs.rb +14 -21
- data/lib/sidekiq-middleware/version.rb +1 -1
- data/lib/sidekiq-middleware/worker.rb +39 -0
- data/test/helper.rb +3 -0
- data/test/test_unique_jobs.rb +129 -111
- metadata +20 -20
- data/lib/sidekiq-middleware/unique_key.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b188c23f68544df2038746bd369ba9d4ab965b3f
|
4
|
+
data.tar.gz: 4c3b61f360e917fd733b247d6aa60349a11b2270
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aca4da5872a73e6da626ff87cccc48653238dae8aa88580837e16605d1d23e8dda8980177f24832af564cb472d21f56b4801fdbe3eca684f389ac4adde9ba30c
|
7
|
+
data.tar.gz: a3eaa745e7d6cfca147602a7845994e3f53f6660b2e7b9a8cf86fd3a31ebdcc14857d49712e2224ac9e8cbc3a21a7cc380854d13d818fb8f9ccbee9ed7cb2d2f
|
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,11 @@
|
|
1
|
-
# Additional sidekiq middleware
|
1
|
+
# Additional sidekiq middleware
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/sidekiq-middleware)
|
4
|
+
[](https://gemnasium.com/krasnoukhov/sidekiq-middleware)
|
5
|
+
[](https://codeclimate.com/github/krasnoukhov/sidekiq-middleware)
|
6
|
+
[](http://travis-ci.org/krasnoukhov/sidekiq-middleware)
|
7
|
+
[](https://coveralls.io/r/krasnoukhov/sidekiq-middleware)
|
8
|
+
|
2
9
|
|
3
10
|
This gem provides additional middleware for [Sidekiq](https://github.com/mperham/sidekiq).
|
4
11
|
|
data/lib/sidekiq-middleware.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'sidekiq-middleware/version'
|
3
|
+
require 'sidekiq-middleware/core_ext'
|
4
|
+
require 'sidekiq-middleware/worker'
|
5
|
+
require 'sidekiq-middleware/server/unique_jobs'
|
6
|
+
require 'sidekiq-middleware/client/unique_jobs'
|
7
|
+
require 'sidekiq-middleware/middleware'
|
@@ -2,37 +2,33 @@ module Sidekiq
|
|
2
2
|
module Middleware
|
3
3
|
module Client
|
4
4
|
class UniqueJobs
|
5
|
-
HASH_KEY_EXPIRATION = 30 * 60
|
6
|
-
|
7
5
|
def call(worker_class, item, queue)
|
8
6
|
worker_class = worker_class.constantize if worker_class.is_a?(String)
|
9
|
-
|
10
|
-
enabled, expiration = worker_class.get_sidekiq_options['unique'],
|
11
|
-
(worker_class.get_sidekiq_options['expiration'] || HASH_KEY_EXPIRATION)
|
7
|
+
enabled = worker_class.unique_enabled?(item)
|
12
8
|
|
13
9
|
if enabled
|
14
|
-
|
10
|
+
expiration = worker_class.unique_exiration
|
15
11
|
job_id = item['jid']
|
12
|
+
unique = false
|
16
13
|
|
17
|
-
#
|
18
|
-
if
|
14
|
+
# Scheduled
|
15
|
+
if item.has_key?('at')
|
19
16
|
# Use expiration period as specified in configuration,
|
20
17
|
# but relative to job schedule time
|
21
|
-
expiration += (
|
22
|
-
payload.delete('at')
|
18
|
+
expiration += (item['at'].to_i - Time.now.to_i)
|
23
19
|
end
|
24
20
|
|
25
|
-
|
21
|
+
unique_key = worker_class.unique_digest(item)
|
26
22
|
|
27
23
|
Sidekiq.redis do |conn|
|
28
|
-
conn.watch(
|
24
|
+
conn.watch(unique_key)
|
29
25
|
|
30
|
-
locked_job_id = conn.get(
|
26
|
+
locked_job_id = conn.get(unique_key)
|
31
27
|
if locked_job_id && locked_job_id != job_id
|
32
28
|
conn.unwatch
|
33
29
|
else
|
34
30
|
unique = conn.multi do
|
35
|
-
conn.setex(
|
31
|
+
conn.setex(unique_key, expiration, job_id)
|
36
32
|
end
|
37
33
|
end
|
38
34
|
end
|
@@ -2,34 +2,27 @@ module Sidekiq
|
|
2
2
|
module Middleware
|
3
3
|
module Server
|
4
4
|
class UniqueJobs
|
5
|
-
|
6
5
|
def call(worker_instance, item, queue)
|
7
|
-
|
6
|
+
worker_class = worker_instance.class
|
7
|
+
enabled = worker_class.unique_enabled?(item)
|
8
8
|
|
9
|
-
|
9
|
+
if enabled
|
10
|
+
begin
|
11
|
+
yield
|
12
|
+
ensure
|
13
|
+
unless worker_class.unique_manual?
|
14
|
+
clear(worker_class, item)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
else
|
10
18
|
yield
|
11
|
-
ensure
|
12
|
-
clear(worker_instance, item, queue) unless manual
|
13
19
|
end
|
14
20
|
end
|
15
21
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
enabled, payload = worker_instance.class.get_sidekiq_options['unique'],
|
20
|
-
item.clone.slice(*%w(class queue args at))
|
21
|
-
|
22
|
-
# Enabled unique scheduled
|
23
|
-
if enabled == :all && payload.has_key?('at')
|
24
|
-
payload.delete('at')
|
22
|
+
def clear(worker_class, item)
|
23
|
+
Sidekiq.redis do |conn|
|
24
|
+
conn.del worker_class.unique_digest(item)
|
25
25
|
end
|
26
|
-
|
27
|
-
Sidekiq::Middleware::UniqueKey.generate(worker_instance.class, payload)
|
28
|
-
end
|
29
|
-
|
30
|
-
def clear(worker_instance, item, queue)
|
31
|
-
enabled = worker_instance.class.get_sidekiq_options['unique']
|
32
|
-
Sidekiq.redis { |conn| conn.del unique_lock_key(worker_instance, item, queue) } if enabled
|
33
26
|
end
|
34
27
|
end
|
35
28
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Middleware
|
3
|
+
module Worker
|
4
|
+
UNIQUE_EXPIRATION = 30 * 60 # 30 minutes
|
5
|
+
|
6
|
+
def unique_digest(item)
|
7
|
+
if respond_to?(:lock)
|
8
|
+
args = item['args']
|
9
|
+
lock(*args)
|
10
|
+
else
|
11
|
+
dumped = Sidekiq.dump_json(item.slice('class', 'queue', 'args'))
|
12
|
+
digest = Digest::MD5.hexdigest(dumped)
|
13
|
+
|
14
|
+
"locks:unique:#{digest}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def unique_exiration
|
19
|
+
get_sidekiq_options['expiration'] || UNIQUE_EXPIRATION
|
20
|
+
end
|
21
|
+
|
22
|
+
def unique_enabled?(item)
|
23
|
+
enabled = get_sidekiq_options['unique']
|
24
|
+
if item.has_key?('at') && enabled != :all
|
25
|
+
enabled = false
|
26
|
+
end
|
27
|
+
enabled
|
28
|
+
end
|
29
|
+
|
30
|
+
def unique_manual?
|
31
|
+
get_sidekiq_options['manual']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Sidekiq::Worker::ClassMethods.class_eval do
|
38
|
+
include Sidekiq::Middleware::Worker
|
39
|
+
end
|
data/test/helper.rb
CHANGED
data/test/test_unique_jobs.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'securerandom'
|
2
1
|
require 'helper'
|
3
2
|
require 'timecop'
|
4
3
|
require 'sidekiq/client'
|
@@ -31,147 +30,166 @@ class TestUniqueJobs < MiniTest::Unit::TestCase
|
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
describe 'when unique option is disabled (unique: false)' do
|
34
|
+
class NotUniqueWorker
|
35
|
+
include Sidekiq::Worker
|
36
|
+
sidekiq_options queue: :not_unique_queue, unique: false
|
37
37
|
|
38
|
-
|
38
|
+
def perform(x)
|
39
|
+
end
|
39
40
|
end
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'does not duplicate messages with enabled unique option' do
|
43
|
-
5.times { UniqueWorker.perform_async('args') }
|
44
|
-
assert_equal 1, Sidekiq.redis { |c| c.llen('queue:unique_queue') }
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'discards non critical information about the message' do
|
48
|
-
5.times { Sidekiq::Client.push('class' => UniqueWorker, 'args' => ['critical'], 'sent_at' => Time.now.to_f, 'non' => 'critical') }
|
49
|
-
assert_equal 1, Sidekiq.redis { |c| c.llen('queue:unique_queue') }
|
50
|
-
end
|
51
|
-
|
52
|
-
class NotUniqueWorker
|
53
|
-
include Sidekiq::Worker
|
54
|
-
sidekiq_options queue: :not_unique_queue, unique: false
|
55
41
|
|
56
|
-
|
42
|
+
it 'duplicates messages' do
|
43
|
+
5.times { NotUniqueWorker.perform_async('args') }
|
44
|
+
assert_equal 5, Sidekiq.redis { |c| c.llen('queue:not_unique_queue') }
|
57
45
|
end
|
58
|
-
end
|
59
46
|
|
60
|
-
|
61
|
-
|
62
|
-
|
47
|
+
it 'duplicates scheduled messages' do
|
48
|
+
at = Time.now.to_f
|
49
|
+
5.times { Sidekiq::Client.push('class' => NotUniqueWorker, 'args' => ['args'], 'at' => at) }
|
50
|
+
assert_equal 5, Sidekiq.redis { |c| c.zcard('schedule') }
|
51
|
+
end
|
63
52
|
end
|
64
53
|
|
65
|
-
|
66
|
-
|
67
|
-
|
54
|
+
describe 'when unique option is enabled (unique: true)' do
|
55
|
+
class UniqueWorker
|
56
|
+
include Sidekiq::Worker
|
57
|
+
sidekiq_options queue: :unique_queue, unique: true
|
68
58
|
|
69
|
-
|
59
|
+
def perform(x)
|
60
|
+
end
|
70
61
|
end
|
71
|
-
end
|
72
62
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
63
|
+
it 'does not duplicate messages' do
|
64
|
+
5.times { UniqueWorker.perform_async('args') }
|
65
|
+
assert_equal 1, Sidekiq.redis { |c| c.llen('queue:unique_queue') }
|
66
|
+
end
|
77
67
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
UniqueScheduledWorker.perform_at queue_time, 'x'
|
83
|
-
end
|
84
|
-
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
85
|
-
assert_equal 0, Sidekiq.redis { |c| c.llen('queue:unique_scheduled_queue') }
|
86
|
-
Sidekiq::Scheduled::Poller.new.poll
|
87
|
-
assert_equal 0, Sidekiq.redis { |c| c.zcard('schedule') }
|
88
|
-
assert_equal 1, Sidekiq.redis { |c| c.llen('queue:unique_scheduled_queue') }
|
89
|
-
end
|
68
|
+
it 'discards non critical information about the message' do
|
69
|
+
5.times { Sidekiq::Client.push('class' => UniqueWorker, 'args' => ['critical'], 'sent_at' => Time.now.to_f, 'non' => 'critical') }
|
70
|
+
assert_equal 1, Sidekiq.redis { |c| c.llen('queue:unique_queue') }
|
71
|
+
end
|
90
72
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
# Process
|
97
|
-
msg = Sidekiq.dump_json('class' => UniqueScheduledWorker.to_s, 'queue' => 'unique_scheduled_queue', 'args' => ['args'])
|
98
|
-
actor = MiniTest::Mock.new
|
99
|
-
actor.expect(:processor_done, nil, [@processor])
|
100
|
-
actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
|
101
|
-
2.times { @boss.expect(:async, actor, []) }
|
102
|
-
work = UnitOfWork.new('default', msg)
|
103
|
-
@processor.process(work)
|
104
|
-
|
105
|
-
# Re-schedule
|
106
|
-
5.times { |t| UniqueScheduledWorker.perform_in((t+1)*60, 'args') }
|
107
|
-
assert_equal 2, Sidekiq.redis { |c| c.zcard('schedule') }
|
73
|
+
it 'duplicates scheduled messages' do
|
74
|
+
at = Time.now.to_f
|
75
|
+
5.times { Sidekiq::Client.push('class' => UniqueWorker, 'args' => ['args'], 'at' => at) }
|
76
|
+
assert_equal 5, Sidekiq.redis { |c| c.zcard('schedule') }
|
77
|
+
end
|
108
78
|
end
|
109
79
|
|
110
|
-
|
111
|
-
|
112
|
-
|
80
|
+
describe 'when unique option is enabled (unique: :all)' do
|
81
|
+
class UniqueScheduledWorker
|
82
|
+
include Sidekiq::Worker
|
83
|
+
sidekiq_options queue: :unique_scheduled_queue, unique: :all
|
113
84
|
|
114
|
-
|
115
|
-
|
85
|
+
def perform(x)
|
86
|
+
end
|
116
87
|
end
|
117
88
|
|
118
|
-
|
119
|
-
|
120
|
-
Sidekiq.redis { |
|
89
|
+
it 'does not duplicate scheduled messages' do
|
90
|
+
5.times { |t| UniqueScheduledWorker.perform_in((t+1)*60, 'args') }
|
91
|
+
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
121
92
|
end
|
122
93
|
|
123
|
-
|
124
|
-
|
125
|
-
|
94
|
+
it 'does correctly handle adding to the worker queue when scheduled' do
|
95
|
+
start_time = Time.now - 60
|
96
|
+
queue_time = start_time + 30
|
97
|
+
Timecop.travel start_time do
|
98
|
+
UniqueScheduledWorker.perform_at queue_time, 'x'
|
99
|
+
end
|
100
|
+
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
101
|
+
assert_equal 0, Sidekiq.redis { |c| c.llen('queue:unique_scheduled_queue') }
|
102
|
+
Sidekiq::Scheduled::Poller.new.poll
|
103
|
+
assert_equal 0, Sidekiq.redis { |c| c.zcard('schedule') }
|
104
|
+
assert_equal 1, Sidekiq.redis { |c| c.llen('queue:unique_scheduled_queue') }
|
126
105
|
end
|
127
|
-
end
|
128
106
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
assert job['jid']
|
134
|
-
assert_equal job['jid'], Sidekiq.redis { |c| c.get('custom:unique:lock:args') }
|
135
|
-
end
|
107
|
+
it 'allows the job to be re-scheduled after processing' do
|
108
|
+
# Schedule
|
109
|
+
5.times { |t| UniqueScheduledWorker.perform_in((t+1)*60, 'args') }
|
110
|
+
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
136
111
|
|
137
|
-
|
138
|
-
|
139
|
-
msg = Sidekiq.dump_json('class' => CustomUniqueWorker.to_s, 'args' => ['something', false])
|
112
|
+
# Process
|
113
|
+
msg = Sidekiq.dump_json('class' => UniqueScheduledWorker.to_s, 'queue' => 'unique_scheduled_queue', 'args' => ['args'])
|
140
114
|
actor = MiniTest::Mock.new
|
141
115
|
actor.expect(:processor_done, nil, [@processor])
|
142
116
|
actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
|
143
117
|
2.times { @boss.expect(:async, actor, []) }
|
144
118
|
work = UnitOfWork.new('default', msg)
|
145
119
|
@processor.process(work)
|
146
|
-
}
|
147
|
-
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
148
|
-
end
|
149
120
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
actor.expect(:processor_done, nil, [@processor])
|
155
|
-
actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
|
156
|
-
2.times { @boss.expect(:async, actor, []) }
|
157
|
-
work = UnitOfWork.new('default', msg)
|
158
|
-
@processor.process(work)
|
159
|
-
}
|
160
|
-
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
121
|
+
# Re-schedule
|
122
|
+
5.times { |t| UniqueScheduledWorker.perform_in((t+1)*60, 'args') }
|
123
|
+
assert_equal 2, Sidekiq.redis { |c| c.zcard('schedule') }
|
124
|
+
end
|
161
125
|
end
|
162
126
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
127
|
+
describe 'when unique and manual options are enabled (unique: :all, manual: true)' do
|
128
|
+
class CustomUniqueWorker
|
129
|
+
include Sidekiq::Worker
|
130
|
+
sidekiq_options queue: :custom_unique_queue, unique: :all, manual: true
|
131
|
+
|
132
|
+
def self.lock(id, unlock)
|
133
|
+
"custom:unique:lock:#{id}"
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.unlock!(id, unlock)
|
137
|
+
lock = self.lock(id, unlock)
|
138
|
+
Sidekiq.redis { |conn| conn.del(lock) }
|
139
|
+
end
|
175
140
|
|
141
|
+
def perform(id, unlock)
|
142
|
+
self.class.unlock!(id, unlock) if unlock
|
143
|
+
CustomUniqueWorker.perform_in(60, id, unlock)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'does not duplicate messages with custom unique lock key' do
|
148
|
+
5.times { CustomUniqueWorker.perform_async('args', false) }
|
149
|
+
assert_equal 1, Sidekiq.redis { |c| c.llen('queue:custom_unique_queue') }
|
150
|
+
job = Sidekiq.load_json Sidekiq.redis { |c| c.lpop('queue:custom_unique_queue') }
|
151
|
+
assert job['jid']
|
152
|
+
assert_equal job['jid'], Sidekiq.redis { |c| c.get('custom:unique:lock:args') }
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'does not allow the job to be duplicated when processing job' do
|
156
|
+
5.times {
|
157
|
+
msg = Sidekiq.dump_json('class' => CustomUniqueWorker.to_s, 'args' => ['something', false])
|
158
|
+
actor = MiniTest::Mock.new
|
159
|
+
actor.expect(:processor_done, nil, [@processor])
|
160
|
+
actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
|
161
|
+
2.times { @boss.expect(:async, actor, []) }
|
162
|
+
work = UnitOfWork.new('default', msg)
|
163
|
+
@processor.process(work)
|
164
|
+
}
|
165
|
+
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'discards non critical information about the message' do
|
169
|
+
5.times {|i|
|
170
|
+
msg = Sidekiq.dump_json('class' => CustomUniqueWorker.to_s, 'args' => ['something', false], 'sent_at' => (Time.now + i*60).to_f)
|
171
|
+
actor = MiniTest::Mock.new
|
172
|
+
actor.expect(:processor_done, nil, [@processor])
|
173
|
+
actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
|
174
|
+
2.times { @boss.expect(:async, actor, []) }
|
175
|
+
work = UnitOfWork.new('default', msg)
|
176
|
+
@processor.process(work)
|
177
|
+
}
|
178
|
+
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'allows a job to be rescheduled when processing using unlock' do
|
182
|
+
5.times {
|
183
|
+
msg = Sidekiq.dump_json('class' => CustomUniqueWorker.to_s, 'args' => ['something', true])
|
184
|
+
actor = MiniTest::Mock.new
|
185
|
+
actor.expect(:processor_done, nil, [@processor])
|
186
|
+
actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
|
187
|
+
2.times { @boss.expect(:async, actor, []) }
|
188
|
+
work = UnitOfWork.new('default', msg)
|
189
|
+
@processor.process(work)
|
190
|
+
}
|
191
|
+
assert_equal 5, Sidekiq.redis { |c| c.zcard('schedule') }
|
192
|
+
end
|
193
|
+
end
|
176
194
|
end
|
177
195
|
end
|
metadata
CHANGED
@@ -1,89 +1,89 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-middleware
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dmitry Krasnoukhov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sidekiq
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 2.12.4
|
20
|
-
- - <
|
20
|
+
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '3'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 2.12.4
|
30
|
-
- - <
|
30
|
+
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '3'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rake
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- -
|
37
|
+
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '0'
|
40
40
|
type: :development
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
|
-
- -
|
44
|
+
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bundler
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
-
- - ~>
|
51
|
+
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '1.0'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
|
-
- - ~>
|
58
|
+
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '1.0'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: minitest
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
|
-
- - ~>
|
65
|
+
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
67
|
version: '3'
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- - ~>
|
72
|
+
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '3'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
76
|
name: timecop
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
|
-
- -
|
79
|
+
- - ">="
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
version: '0'
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
|
-
- -
|
86
|
+
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '0'
|
89
89
|
description: Additional sidekiq middleware
|
@@ -93,8 +93,8 @@ executables: []
|
|
93
93
|
extensions: []
|
94
94
|
extra_rdoc_files: []
|
95
95
|
files:
|
96
|
-
- .gitignore
|
97
|
-
- .travis.yml
|
96
|
+
- ".gitignore"
|
97
|
+
- ".travis.yml"
|
98
98
|
- CHANGES.md
|
99
99
|
- Gemfile
|
100
100
|
- LICENSE
|
@@ -105,8 +105,8 @@ files:
|
|
105
105
|
- lib/sidekiq-middleware/core_ext.rb
|
106
106
|
- lib/sidekiq-middleware/middleware.rb
|
107
107
|
- lib/sidekiq-middleware/server/unique_jobs.rb
|
108
|
-
- lib/sidekiq-middleware/unique_key.rb
|
109
108
|
- lib/sidekiq-middleware/version.rb
|
109
|
+
- lib/sidekiq-middleware/worker.rb
|
110
110
|
- sidekiq-middleware.gemspec
|
111
111
|
- test/helper.rb
|
112
112
|
- test/test_core_ext.rb
|
@@ -120,17 +120,17 @@ require_paths:
|
|
120
120
|
- lib
|
121
121
|
required_ruby_version: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- -
|
123
|
+
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
127
|
requirements:
|
128
|
-
- -
|
128
|
+
- - ">="
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
131
|
requirements: []
|
132
132
|
rubyforge_project:
|
133
|
-
rubygems_version: 2.0.
|
133
|
+
rubygems_version: 2.2.0.rc.1
|
134
134
|
signing_key:
|
135
135
|
specification_version: 4
|
136
136
|
summary: Additional sidekiq middleware
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module Sidekiq
|
2
|
-
module Middleware
|
3
|
-
module UniqueKey
|
4
|
-
def self.generate(worker_class, payload)
|
5
|
-
if worker_class.respond_to?(:lock)
|
6
|
-
worker_class.lock(*payload['args'])
|
7
|
-
else
|
8
|
-
json = Sidekiq.dump_json(payload)
|
9
|
-
"locks:unique:#{Digest::MD5.hexdigest(json)}"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|