sidekiq-middleware 0.0.2 → 0.0.3
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.
- data/README.md +20 -20
- data/lib/sidekiq-middleware.rb +1 -0
- data/lib/sidekiq-middleware/client/unique_jobs.rb +7 -12
- data/lib/sidekiq-middleware/core_ext.rb +11 -0
- data/lib/sidekiq-middleware/server/unique_jobs.rb +7 -11
- data/lib/sidekiq-middleware/version.rb +1 -1
- data/test/helper.rb +3 -0
- data/test/test_core_ext.rb +28 -0
- data/test/test_unique_jobs.rb +20 -6
- metadata +7 -4
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Additional sidekiq middleware [](http://travis-ci.org/krasnoukhov/sidekiq-middleware)
|
2
2
|
|
3
|
-
This gem provides additional middleware for [Sidekiq](github.com/mperham/sidekiq
|
3
|
+
This gem provides additional middleware for [Sidekiq](https://github.com/mperham/sidekiq).
|
4
4
|
|
5
5
|
See [Sidekiq Wiki](https://github.com/mperham/sidekiq/wiki/Middleware) for more details.
|
6
6
|
|
@@ -29,26 +29,26 @@ Provides uniqueness for jobs.
|
|
29
29
|
Example worker:
|
30
30
|
|
31
31
|
```ruby
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
32
|
+
class UniqueWorker
|
33
|
+
include Sidekiq::Worker
|
34
|
+
|
35
|
+
sidekiq_options({
|
36
|
+
# Should be set to true (enables uniqueness for async jobs)
|
37
|
+
# or :all (enables uniqueness for both async and scheduled jobs)
|
38
|
+
unique: :all,
|
39
|
+
|
40
|
+
# Set this to true in case your job schedules itself
|
41
|
+
forever: true,
|
42
|
+
|
43
|
+
# Unique expiration (optional, default is 30 minutes)
|
44
|
+
# For scheduled jobs calculates automatically if not provided
|
45
|
+
expiration: 24 * 60 * 60
|
46
|
+
})
|
47
|
+
|
48
|
+
def perform
|
49
|
+
# Your code goes here
|
51
50
|
end
|
51
|
+
end
|
52
52
|
```
|
53
53
|
|
54
54
|
## Contributing
|
data/lib/sidekiq-middleware.rb
CHANGED
@@ -5,23 +5,19 @@ module Sidekiq
|
|
5
5
|
HASH_KEY_EXPIRATION = 30 * 60
|
6
6
|
|
7
7
|
def call(worker_class, item, queue)
|
8
|
-
enabled = worker_class.get_sidekiq_options['unique']
|
8
|
+
enabled, expiration = worker_class.get_sidekiq_options['unique'],
|
9
|
+
(worker_class.get_sidekiq_options['expiration'] || HASH_KEY_EXPIRATION)
|
9
10
|
|
10
11
|
if enabled
|
11
|
-
unique = false
|
12
|
+
unique, payload = false, item.clone.slice(%w(class queue args at))
|
12
13
|
|
13
14
|
# Enabled unique scheduled
|
14
|
-
if enabled == :all &&
|
15
|
-
expiration =
|
16
|
-
payload = item.clone
|
15
|
+
if enabled == :all && payload.has_key?('at')
|
16
|
+
expiration = (payload['at'].to_i - Time.now.to_i)
|
17
17
|
payload.delete('at')
|
18
|
-
payload.delete('jid')
|
19
|
-
else
|
20
|
-
expiration = worker_class.get_sidekiq_options['expiration'] || HASH_KEY_EXPIRATION
|
21
|
-
payload = item.clone
|
22
|
-
payload.delete('jid')
|
23
18
|
end
|
24
|
-
|
19
|
+
|
20
|
+
payload_hash = Digest::MD5.hexdigest(Sidekiq.dump_json(payload))
|
25
21
|
|
26
22
|
Sidekiq.redis do |conn|
|
27
23
|
conn.watch(payload_hash)
|
@@ -40,7 +36,6 @@ module Sidekiq
|
|
40
36
|
yield
|
41
37
|
end
|
42
38
|
end
|
43
|
-
|
44
39
|
end
|
45
40
|
end
|
46
41
|
end
|
@@ -18,22 +18,18 @@ module Sidekiq
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def clear(worker_instance, item, queue)
|
21
|
-
|
21
|
+
# Only enforce uniqueness across class, queue, args, and at.
|
22
|
+
# Useful when middleware uses the payload to store metadata.
|
23
|
+
enabled, payload = worker_instance.class.get_sidekiq_options['unique'],
|
24
|
+
item.clone.slice(%w(class queue args at))
|
22
25
|
|
23
26
|
# Enabled unique scheduled
|
24
|
-
if enabled == :all &&
|
25
|
-
payload = item.clone
|
27
|
+
if enabled == :all && payload.has_key?('at')
|
26
28
|
payload.delete('at')
|
27
|
-
payload.delete('jid')
|
28
|
-
else
|
29
|
-
payload = item.clone
|
30
|
-
payload.delete('jid')
|
31
29
|
end
|
32
|
-
payload_hash = Digest::MD5.hexdigest(Sidekiq.dump_json(Hash[payload.sort]))
|
33
|
-
|
34
|
-
Sidekiq.redis { |conn| conn.del(payload_hash) }
|
35
|
-
end
|
36
30
|
|
31
|
+
Sidekiq.redis { |conn| conn.del Digest::MD5.hexdigest(Sidekiq.dump_json(payload)) }
|
32
|
+
end
|
37
33
|
end
|
38
34
|
end
|
39
35
|
end
|
data/test/helper.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'sidekiq-middleware'
|
3
|
+
|
4
|
+
class TestCoreExt < MiniTest::Unit::TestCase
|
5
|
+
describe 'for an empty array' do
|
6
|
+
it 'should be an ampty hash' do
|
7
|
+
assert_equal({}, {:foo => "bar"}.slice([]))
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'for items not in the hash' do
|
12
|
+
it 'should be an empty hash' do
|
13
|
+
assert_equal({}, {:foo => "bar", :foobar => "baz"}.slice(:baz, :foobaz))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'for items in the hash' do
|
18
|
+
it 'should be the attributes' do
|
19
|
+
assert_equal({:foo => "bar"}, {:foo => "bar", :foobar => "baz"}.slice(:foo))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'when all items are in the hash' do
|
24
|
+
it 'should be the hash' do
|
25
|
+
assert_equal({:foo => "bar", :foobar => "baz"}, {:foo => "bar", :foobar => "baz"}.slice(:foo, :foobar))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/test/test_unique_jobs.rb
CHANGED
@@ -10,7 +10,6 @@ class TestUniqueJobs < MiniTest::Unit::TestCase
|
|
10
10
|
before do
|
11
11
|
@boss = MiniTest::Mock.new
|
12
12
|
@processor = ::Sidekiq::Processor.new(@boss)
|
13
|
-
Celluloid.logger = nil
|
14
13
|
|
15
14
|
Sidekiq.redis = REDIS
|
16
15
|
Sidekiq.redis {|c| c.flushdb }
|
@@ -29,6 +28,11 @@ class TestUniqueJobs < MiniTest::Unit::TestCase
|
|
29
28
|
assert_equal 1, Sidekiq.redis { |c| c.llen('queue:unique_queue') }
|
30
29
|
end
|
31
30
|
|
31
|
+
it 'discards non critical information about the message' do
|
32
|
+
5.times { Sidekiq::Client.push('class' => UniqueWorker, 'args' => ['critical'], 'sent_at' => Time.now.to_f, 'non' => 'critical') }
|
33
|
+
assert_equal 1, Sidekiq.redis { |c| c.llen('queue:unique_queue') }
|
34
|
+
end
|
35
|
+
|
32
36
|
class NotUniqueWorker
|
33
37
|
include Sidekiq::Worker
|
34
38
|
sidekiq_options queue: :not_unique_queue, unique: false
|
@@ -53,17 +57,27 @@ class TestUniqueJobs < MiniTest::Unit::TestCase
|
|
53
57
|
|
54
58
|
it 'does not duplicate scheduled messages with enabled unique option' do
|
55
59
|
5.times { |t| UniqueScheduledWorker.perform_in((t+1)*60, 'args') }
|
56
|
-
assert_equal 1, Sidekiq.redis { |c| c.
|
60
|
+
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
57
61
|
end
|
58
62
|
|
59
|
-
it '
|
63
|
+
it 'allows the job to reschedule itself with enabled forever option' do
|
60
64
|
5.times {
|
61
|
-
msg = Sidekiq.dump_json(
|
65
|
+
msg = Sidekiq.dump_json('class' => UniqueScheduledWorker.to_s, 'args' => ['something'])
|
66
|
+
@boss.expect(:processor_done!, nil, [@processor])
|
67
|
+
@processor.process(msg, 'default')
|
68
|
+
@boss.verify
|
69
|
+
}
|
70
|
+
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'discards non critical information about the message' do
|
74
|
+
5.times {|i|
|
75
|
+
msg = Sidekiq.dump_json('class' => UniqueScheduledWorker.to_s, 'args' => ['something'], 'sent_at' => (Time.now + i*60).to_f)
|
62
76
|
@boss.expect(:processor_done!, nil, [@processor])
|
63
77
|
@processor.process(msg, 'default')
|
64
78
|
@boss.verify
|
65
79
|
}
|
66
|
-
assert_equal 1, Sidekiq.redis { |c| c.
|
80
|
+
assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
|
67
81
|
end
|
68
82
|
end
|
69
|
-
end
|
83
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-middleware
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sidekiq
|
@@ -74,11 +74,13 @@ files:
|
|
74
74
|
- Rakefile
|
75
75
|
- lib/sidekiq-middleware.rb
|
76
76
|
- lib/sidekiq-middleware/client/unique_jobs.rb
|
77
|
+
- lib/sidekiq-middleware/core_ext.rb
|
77
78
|
- lib/sidekiq-middleware/middleware.rb
|
78
79
|
- lib/sidekiq-middleware/server/unique_jobs.rb
|
79
80
|
- lib/sidekiq-middleware/version.rb
|
80
81
|
- sidekiq-middleware.gemspec
|
81
82
|
- test/helper.rb
|
83
|
+
- test/test_core_ext.rb
|
82
84
|
- test/test_unique_jobs.rb
|
83
85
|
homepage: http://github.com/krasnoukhov/sidekiq-middleware
|
84
86
|
licenses: []
|
@@ -94,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
96
|
version: '0'
|
95
97
|
segments:
|
96
98
|
- 0
|
97
|
-
hash:
|
99
|
+
hash: 4144828327274564708
|
98
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
101
|
none: false
|
100
102
|
requirements:
|
@@ -103,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
105
|
version: '0'
|
104
106
|
segments:
|
105
107
|
- 0
|
106
|
-
hash:
|
108
|
+
hash: 4144828327274564708
|
107
109
|
requirements: []
|
108
110
|
rubyforge_project:
|
109
111
|
rubygems_version: 1.8.24
|
@@ -112,4 +114,5 @@ specification_version: 3
|
|
112
114
|
summary: Additional sidekiq middleware
|
113
115
|
test_files:
|
114
116
|
- test/helper.rb
|
117
|
+
- test/test_core_ext.rb
|
115
118
|
- test/test_unique_jobs.rb
|