sidekiq-unique-jobs 2.2.1 → 2.3.2

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.

data/Gemfile CHANGED
@@ -1,20 +1,14 @@
1
1
  source 'http://rubygems.org'
2
2
  gemspec
3
3
 
4
- gem 'celluloid'
5
- gem 'slim'
6
- gem 'sprockets'
7
- gem 'sass'
8
- gem 'rails', '3.2.8'
9
- gem 'sqlite3'
10
-
11
4
  group :test do
12
5
  gem 'simplecov', :require => false
13
6
  end
14
7
 
15
8
  group :development do
9
+ gem 'activesupport'
16
10
  gem 'pry'
17
11
  gem 'pry-doc'
18
12
  gem 'pry-stack_explorer'
19
13
  gem 'pry-debugger'
20
- end
14
+ end
data/README.md CHANGED
@@ -24,6 +24,12 @@ All that is required is that you specifically set the sidekiq option for *unique
24
24
  sidekiq_options unique: true
25
25
  ```
26
26
 
27
+ 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:
28
+
29
+ ```ruby
30
+ sidekiq_options unique: true, unique_job_expiration: 120 * 60 # 2 hours
31
+ ```
32
+
27
33
  Requiring the gem in your gemfile should be sufficient to enable unique jobs.
28
34
 
29
35
 
@@ -1,5 +1,4 @@
1
- require 'sidekiq/middleware/chain'
2
- require 'sidekiq/processor'
1
+ require 'sidekiq'
3
2
 
4
3
  Sidekiq.configure_server do |config|
5
4
  config.server_middleware do |chain|
@@ -13,4 +12,4 @@ Sidekiq.configure_client do |config|
13
12
  require 'sidekiq-unique-jobs/middleware/client/unique_jobs'
14
13
  chain.add SidekiqUniqueJobs::Middleware::Client::UniqueJobs
15
14
  end
16
- end
15
+ end
@@ -9,10 +9,12 @@ module SidekiqUniqueJobs
9
9
  def call(worker_class, item, queue)
10
10
 
11
11
  enabled = worker_class.get_sidekiq_options['unique']
12
+ unique_job_expiration = worker_class.get_sidekiq_options['unique_job_expiration']
12
13
 
13
14
  if enabled
14
15
 
15
- payload_hash = Digest::MD5.hexdigest(Sidekiq.dump_json(item['args']))
16
+ md5_arguments = {:class => item['class'], :queue => item['queue'], :args => item['args']}
17
+ payload_hash = Digest::MD5.hexdigest(Sidekiq.dump_json(md5_arguments))
16
18
 
17
19
  unique = false
18
20
 
@@ -23,8 +25,8 @@ module SidekiqUniqueJobs
23
25
  if conn.get(payload_hash)
24
26
  conn.unwatch
25
27
  else
26
- expires_at = HASH_KEY_EXPIRATION
27
- expires_at = ((Time.at(item['at']) - Time.now.utc) * 24 * 60 * 60).to_i if item['at']
28
+ expires_at = unique_job_expiration || HASH_KEY_EXPIRATION
29
+ expires_at = ((Time.at(item['at']) - Time.now.utc) + expires_at).to_i if item['at']
28
30
 
29
31
  unique = conn.multi do
30
32
  conn.setex(payload_hash, expires_at, 1)
@@ -40,4 +42,4 @@ module SidekiqUniqueJobs
40
42
  end
41
43
  end
42
44
  end
43
- end
45
+ end
@@ -5,13 +5,22 @@ module SidekiqUniqueJobs
5
5
  module Server
6
6
  class UniqueJobs
7
7
  def call(*args)
8
+ logger.info("About to process a job with args #{args.inspect}")
8
9
  yield
10
+ logger.info("Done processing a job with args #{args.inspect}")
9
11
  ensure
10
- json = Sidekiq.dump_json(args[1])
11
- hash = Digest::MD5.hexdigest(json)
12
+ item = args[1]
13
+ md5_arguments = {:class => item['class'], :queue => item['queue'], :args => item['args']}
14
+ hash = Digest::MD5.hexdigest(Sidekiq.dump_json(md5_arguments))
12
15
  Sidekiq.redis {|conn| conn.del(hash) }
13
16
  end
17
+
18
+ protected
19
+
20
+ def logger
21
+ Sidekiq.logger
22
+ end
14
23
  end
15
24
  end
16
25
  end
17
- end
26
+ end
@@ -1,3 +1,3 @@
1
1
  module SidekiqUniqueJobs
2
- VERSION = "2.2.1"
2
+ VERSION = "2.3.2"
3
3
  end
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "sidekiq-unique-jobs"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = SidekiqUniqueJobs::VERSION
17
- gem.add_dependency 'sidekiq', '~> 2.2.0'
17
+ gem.add_dependency 'sidekiq', '>= 2.2.0'
18
18
  gem.add_development_dependency 'minitest', '~> 3'
19
19
  gem.add_development_dependency 'sinatra'
20
20
  gem.add_development_dependency 'slim'
@@ -2,12 +2,14 @@ require 'helper'
2
2
  require 'sidekiq/worker'
3
3
  require "sidekiq-unique-jobs"
4
4
  require 'sidekiq/scheduled'
5
+ require 'sidekiq-unique-jobs/middleware/server/unique_jobs'
5
6
 
6
7
  class TestClient < MiniTest::Unit::TestCase
7
8
  describe 'with real redis' do
8
9
  before do
9
10
  Sidekiq.redis = REDIS
10
11
  Sidekiq.redis {|c| c.flushdb }
12
+ QueueWorker.sidekiq_options :unique => nil, :unique_job_expiration => nil
11
13
  end
12
14
 
13
15
  class QueueWorker
@@ -17,15 +19,47 @@ class TestClient < MiniTest::Unit::TestCase
17
19
  end
18
20
  end
19
21
 
22
+ # This spec sometimes fails (unless it's the only spec that runs)
23
+ # Not sure why, we tried a wide variety of ways to make sure that
24
+ # there aren't side effects between tests and it still happens
25
+ it 'is able to enqueue after the server middleware completes' do
26
+ QueueWorker.sidekiq_options :unique => true
27
+ request_item = {'class' => TestClient::QueueWorker, 'queue' => 'customqueue', 'args' => ["some arg"]}
28
+
29
+ Sidekiq::Client.push(request_item.dup)
30
+ assert_equal 1, Sidekiq.redis {|c| c.llen("queue:customqueue") }
31
+
32
+ # Simulate sidekiq processing the job
33
+ Sidekiq.redis {|c| c.lpop("queue:customqueue")}
34
+ assert_equal 0, Sidekiq.redis {|c| c.llen("queue:customqueue") }
35
+
36
+ SidekiqUniqueJobs::Middleware::Server::UniqueJobs.new.call("dummy arg", request_item.dup) {}
37
+
38
+ Sidekiq::Client.push(request_item.dup)
39
+ assert_equal 1, Sidekiq.redis {|c| c.llen("queue:customqueue") }
40
+ end
41
+
20
42
  it 'does not push duplicate messages when configured for unique only' do
21
43
  QueueWorker.sidekiq_options :unique => true
22
- 10.times { Sidekiq::Client.push('class' => QueueWorker, 'args' => [1, 2]) }
44
+ 10.times { Sidekiq::Client.push('class' => TestClient::QueueWorker, 'queue' => 'customqueue', 'args' => [1, 2]) }
23
45
  assert_equal 1, Sidekiq.redis {|c| c.llen("queue:customqueue") }
24
46
  end
25
47
 
48
+ it 'sets an expiration when provided by sidekiq options' do
49
+ one_hour_expiration = 60 * 60
50
+ QueueWorker.sidekiq_options :unique => true, :unique_job_expiration => one_hour_expiration
51
+ Sidekiq::Client.push('class' => TestClient::QueueWorker, 'queue' => 'customqueue', 'args' => [1, 2])
52
+
53
+ md5_arguments = {:class => "TestClient::QueueWorker", :queue => "customqueue", :args => [1, 2]}
54
+ payload_hash = Digest::MD5.hexdigest(Sidekiq.dump_json(md5_arguments))
55
+ actual_expires_at = Sidekiq.redis {|c| c.ttl(payload_hash) }
56
+
57
+ assert_in_delta one_hour_expiration, actual_expires_at, 2
58
+ end
59
+
26
60
  it 'does push duplicate messages when not configured for unique only' do
27
61
  QueueWorker.sidekiq_options :unique => false
28
- 10.times { Sidekiq::Client.push('class' => QueueWorker, 'args' => [1, 2]) }
62
+ 10.times { Sidekiq::Client.push('class' => TestClient::QueueWorker, 'queue' => 'customqueue', 'args' => [1, 2]) }
29
63
  assert_equal 10, Sidekiq.redis {|c| c.llen("queue:customqueue") }
30
64
  end
31
65
 
@@ -36,16 +70,16 @@ class TestClient < MiniTest::Unit::TestCase
36
70
  QueueWorker.sidekiq_options :unique => true
37
71
 
38
72
  at = 15.minutes.from_now
39
- expected_expires_at = (Time.at(at) - Time.now.utc).to_f
73
+ expected_expires_at = (Time.at(at) - Time.now.utc) + SidekiqUniqueJobs::Middleware::Client::UniqueJobs::HASH_KEY_EXPIRATION
40
74
 
41
75
  QueueWorker.perform_in(at, 'mike')
42
- payload_hash = Digest::MD5.hexdigest(Sidekiq.dump_json(['mike']))
76
+ md5_arguments = {:class => "TestClient::QueueWorker", :queue => "customqueue", :args => ['mike']}
77
+ payload_hash = Digest::MD5.hexdigest(Sidekiq.dump_json(md5_arguments))
43
78
 
44
79
  # deconstruct this into a time format we can use to get a decent delta for
45
- actual_expires_at = Sidekiq.redis {|c| c.ttl(payload_hash).to_f / 24 / 60 / 60 }
46
-
47
- assert_in_delta expected_expires_at, actual_expires_at, 0.05
80
+ actual_expires_at = Sidekiq.redis {|c| c.ttl(payload_hash) }
48
81
 
82
+ assert_in_delta expected_expires_at, actual_expires_at, 2
49
83
  end
50
84
  end
51
- end
85
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-unique-jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,14 +9,14 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-19 00:00:00.000000000 Z
12
+ date: 2012-09-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sidekiq
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
21
  version: 2.2.0
22
22
  type: :runtime
@@ -24,7 +24,7 @@ dependencies:
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: 2.2.0
30
30
  - !ruby/object:Gem::Dependency
@@ -158,21 +158,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
158
158
  - - ! '>='
159
159
  - !ruby/object:Gem::Version
160
160
  version: '0'
161
- segments:
162
- - 0
163
- hash: -556960269690268684
164
161
  required_rubygems_version: !ruby/object:Gem::Requirement
165
162
  none: false
166
163
  requirements:
167
164
  - - ! '>='
168
165
  - !ruby/object:Gem::Version
169
166
  version: '0'
170
- segments:
171
- - 0
172
- hash: -556960269690268684
173
167
  requirements: []
174
168
  rubyforge_project:
175
- rubygems_version: 1.8.24
169
+ rubygems_version: 1.8.23
176
170
  signing_key:
177
171
  specification_version: 3
178
172
  summary: The unique jobs that were removed from sidekiq