sidekiq-middleware 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Additional sidekiq middleware [![Build Status](https://secure.travis-ci.org/krasnoukhov/sidekiq-middleware.png)](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
- 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
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
@@ -1,5 +1,6 @@
1
1
  require "digest"
2
2
  require "sidekiq-middleware/version"
3
+ require "sidekiq-middleware/core_ext"
3
4
  require "sidekiq-middleware/server/unique_jobs"
4
5
  require "sidekiq-middleware/client/unique_jobs"
5
6
  require "sidekiq-middleware/middleware"
@@ -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 && item.has_key?('at')
15
- expiration = worker_class.get_sidekiq_options['expiration'] || (item['at'].to_i - Time.new.to_i)
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
- payload_hash = Digest::MD5.hexdigest(Sidekiq.dump_json(Hash[payload.sort]))
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
@@ -0,0 +1,11 @@
1
+ class Hash
2
+ def slice(*items)
3
+ items = items.to_a.flatten
4
+
5
+ {}.tap do |hash|
6
+ items.each do |item|
7
+ hash[item] = self[item] if self[item]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -18,22 +18,18 @@ module Sidekiq
18
18
  end
19
19
 
20
20
  def clear(worker_instance, item, queue)
21
- enabled = worker_instance.class.get_sidekiq_options['unique']
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 && item.has_key?('at')
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
@@ -1,5 +1,5 @@
1
1
  module Sidekiq
2
2
  module Middleware
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
data/test/helper.rb CHANGED
@@ -8,6 +8,9 @@ require 'minitest/unit'
8
8
  require 'minitest/pride'
9
9
  require 'minitest/autorun'
10
10
 
11
+ require 'celluloid'
12
+ Celluloid.logger = nil
13
+
11
14
  require 'sidekiq'
12
15
  require 'sidekiq/util'
13
16
  require 'sidekiq-middleware'
@@ -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
@@ -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.zrangebyscore('schedule', '-inf', '+inf').length }
60
+ assert_equal 1, Sidekiq.redis { |c| c.zcard('schedule') }
57
61
  end
58
62
 
59
- it 'once schedules job in future with enabled forever option' do
63
+ it 'allows the job to reschedule itself with enabled forever option' do
60
64
  5.times {
61
- msg = Sidekiq.dump_json({ 'class' => UniqueScheduledWorker.to_s, 'args' => ['forever'] })
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.zrangebyscore('schedule', '-inf', '+inf').length }
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.2
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-09-05 00:00:00.000000000 Z
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: -2849267342138572133
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: -2849267342138572133
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