sidekiq-unique-jobs 5.0.0 → 5.0.1

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.

Potentially problematic release.


This version of sidekiq-unique-jobs might be problematic. Click here for more details.

Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -31
  3. data/.editorconfig +2 -2
  4. data/.rubocop.yml +1 -1
  5. data/.travis.yml +4 -4
  6. data/CHANGELOG.md +7 -0
  7. data/README.md +2 -6
  8. data/lib/sidekiq-unique-jobs.rb +5 -1
  9. data/lib/sidekiq/simulator.rb +3 -4
  10. data/lib/sidekiq_unique_jobs/cli.rb +27 -5
  11. data/lib/sidekiq_unique_jobs/lock/until_executed.rb +6 -14
  12. data/lib/sidekiq_unique_jobs/scripts.rb +8 -6
  13. data/lib/sidekiq_unique_jobs/scripts/acquire_lock.rb +45 -0
  14. data/lib/sidekiq_unique_jobs/scripts/release_lock.rb +47 -0
  15. data/lib/sidekiq_unique_jobs/testing.rb +1 -1
  16. data/lib/sidekiq_unique_jobs/unique_args.rb +3 -3
  17. data/lib/sidekiq_unique_jobs/unlockable.rb +4 -18
  18. data/lib/sidekiq_unique_jobs/util.rb +21 -2
  19. data/lib/sidekiq_unique_jobs/version.rb +1 -1
  20. data/rails_example/.env +1 -1
  21. data/rails_example/Gemfile +1 -0
  22. data/rails_example/Procfile +1 -1
  23. data/rails_example/app/workers/simple_worker.rb +1 -1
  24. data/rails_example/app/workers/slow_until_executing_worker.rb +1 -1
  25. data/rails_example/app/workers/spawn_simple_worker.rb +1 -1
  26. data/rails_example/app/workers/while_executing_worker.rb +12 -0
  27. data/rails_example/app/workers/without_argument_worker.rb +1 -1
  28. data/sidekiq-unique-jobs.gemspec +1 -0
  29. data/spec/jobs/another_unique_job.rb +1 -1
  30. data/spec/jobs/my_job.rb +1 -1
  31. data/spec/jobs/unique_job_with_filter_method.rb +1 -1
  32. data/spec/jobs/unique_on_all_queues_job.rb +1 -1
  33. data/spec/jobs/until_executed_job.rb +1 -1
  34. data/spec/jobs/while_executing_job.rb +1 -1
  35. data/spec/lib/sidekiq_unique_jobs/cli_spec.rb +183 -0
  36. data/spec/lib/sidekiq_unique_jobs/client/middleware_spec.rb +1 -9
  37. data/spec/lib/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +0 -2
  38. data/spec/lib/sidekiq_unique_jobs/script_mock_spec.rb +1 -3
  39. data/spec/lib/sidekiq_unique_jobs/scripts/acquire_lock_spec.rb +50 -0
  40. data/spec/lib/sidekiq_unique_jobs/scripts/release_lock_spec.rb +41 -0
  41. data/spec/lib/sidekiq_unique_jobs/scripts_spec.rb +4 -8
  42. data/spec/lib/sidekiq_unique_jobs/server/middleware_spec.rb +0 -5
  43. data/spec/lib/sidekiq_unique_jobs/sidekiq_testing_enabled_spec.rb +0 -19
  44. data/spec/lib/sidekiq_unique_jobs/sidekiq_unique_ext_spec.rb +0 -5
  45. data/spec/lib/sidekiq_unique_jobs/unlockable_spec.rb +0 -1
  46. data/spec/lib/sidekiq_unique_jobs/util_spec.rb +54 -26
  47. data/spec/spec_helper.rb +40 -2
  48. data/spec/support/matchers/redis_matchers.rb +16 -6
  49. metadata +22 -2
@@ -6,10 +6,6 @@ RSpec.describe SidekiqUniqueJobs::Scripts do
6
6
  ANOTHER_JID ||= 'anotherjid'.freeze
7
7
 
8
8
  context 'class methods' do
9
- before do
10
- Sidekiq.redis(&:flushdb)
11
- Sidekiq::Worker.clear_all
12
- end
13
9
  subject { SidekiqUniqueJobs::Scripts }
14
10
 
15
11
  it { is_expected.to respond_to(:call).with(3).arguments }
@@ -34,12 +30,12 @@ RSpec.describe SidekiqUniqueJobs::Scripts do
34
30
  context 'when job is unique' do
35
31
  specify { expect(lock_for).to eq(1) }
36
32
  specify do
37
- expect(lock_for(0.5)).to eq(1)
38
- expect(Redis)
33
+ expect(lock_for(2)).to eq(1)
34
+ expect(SidekiqUniqueJobs)
39
35
  .to have_key(UNIQUE_KEY)
40
36
  .for_seconds(1)
41
- .with_value('fuckit')
42
- sleep 0.5
37
+ .with_value(JID)
38
+ sleep 2
43
39
  expect(lock_for).to eq(1)
44
40
  end
45
41
 
@@ -11,11 +11,6 @@ RSpec.describe SidekiqUniqueJobs::Server::Middleware do
11
11
  SidekiqUniqueJobs::UniqueArgs.digest(item)
12
12
  end
13
13
 
14
- before do
15
- Sidekiq.redis = REDIS
16
- Sidekiq.redis(&:flushdb)
17
- end
18
-
19
14
  describe '#call' do
20
15
  context 'when unique is disabled' do
21
16
  it 'does not use locking' do
@@ -5,25 +5,6 @@ require 'sidekiq/scheduled'
5
5
 
6
6
  RSpec.describe 'When Sidekiq::Testing is enabled' do
7
7
  describe 'when set to :fake!', sidekiq: :fake do
8
- before do
9
- SidekiqUniqueJobs.configure do |config|
10
- config.redis_test_mode = :redis
11
- end
12
- Sidekiq.redis = REDIS
13
- Sidekiq.redis(&:flushdb)
14
- Sidekiq::Worker.clear_all
15
- if Sidekiq::Testing.respond_to?(:server_middleware)
16
- Sidekiq::Testing.server_middleware do |chain|
17
- chain.add SidekiqUniqueJobs::Server::Middleware
18
- end
19
- end
20
- end
21
-
22
- after do
23
- Sidekiq.redis(&:flushdb)
24
- Sidekiq::Testing.server_middleware(&:clear) if Sidekiq::Testing.respond_to?(:server_middleware)
25
- end
26
-
27
8
  context 'with unique worker' do
28
9
  it 'does not push duplicate messages' do
29
10
  param = 'work'
@@ -6,11 +6,6 @@ require 'sidekiq_unique_jobs/client/middleware'
6
6
  require 'sidekiq_unique_jobs/sidekiq_unique_ext'
7
7
 
8
8
  RSpec.describe 'Sidekiq::Api' do
9
- before do
10
- Sidekiq.redis = REDIS
11
- Sidekiq.redis(&:flushdb)
12
- end
13
-
14
9
  let(:item) do
15
10
  { 'class' => JustAWorker,
16
11
  'queue' => 'testqueue',
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe SidekiqUniqueJobs::Unlockable do
4
- before { Sidekiq.redis(&:flushdb) }
5
4
  def item_with_digest
6
5
  SidekiqUniqueJobs::UniqueArgs.digest(item)
7
6
  item
@@ -1,47 +1,62 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe SidekiqUniqueJobs::Util do
4
- let(:keys) { %w[uniquejobs:keyz] }
5
-
6
- def set(key, value)
7
- described_class.connection do |c|
8
- c.set(key, value)
9
- expect(c.keys('*')).to match_array([key])
10
- end
4
+ let(:job) do
5
+ {
6
+ 'class' => 'MyUniqueJob',
7
+ 'args' => [[1, 2]],
8
+ 'at' => 1_492_341_850.358196,
9
+ 'retry' => true,
10
+ 'queue' => 'customqueue',
11
+ 'unique' => :until_executed,
12
+ 'unique_expiration' => 7200,
13
+ 'retry_count' => 10,
14
+ 'jid' => jid,
15
+ 'created_at' => 1_492_341_790.358217,
16
+ }
11
17
  end
18
+ let(:unique_args) { SidekiqUniqueJobs::UniqueArgs.new(job) }
19
+ let(:unique_key) { unique_args.unique_digest }
20
+ let(:jid) { 'e3049b05b0bd9c809182bbe0' }
12
21
 
13
- before(:each) do
14
- Sidekiq.redis = REDIS
15
- Sidekiq.redis(&:flushdb)
22
+ def acquire_lock
23
+ SidekiqUniqueJobs::Scripts::AcquireLock.execute(nil, unique_key, jid, 1)
16
24
  end
17
25
 
18
26
  describe '.keys' do
19
27
  end
20
28
 
21
29
  describe '.del' do
22
- context 'given a key named "keyz" with value "valz"' do
23
- before do
24
- set('uniquejobs:keyz', 'valz')
25
- end
30
+ before do
31
+ acquire_lock
32
+ end
26
33
 
27
- it 'deletes the keys by pattern' do
28
- expect(described_class.del('*', 100, false)).to eq(1)
29
- end
34
+ it 'deletes the keys by pattern' do
35
+ expect(described_class.del(described_class::SCAN_PATTERN, 100, false)).to eq(1)
36
+ end
30
37
 
31
- it 'deletes the keys by pattern' do
32
- expect(described_class.del('keyz', 100, false)).to eq(1)
33
- end
38
+ it 'deletes the keys by distinct key' do
39
+ expect(described_class.del(unique_key, 100, false)).to eq(1)
34
40
  end
35
41
  end
36
42
 
37
- describe '.prefix' do
38
- context 'when .unique_prefix is nil?' do
39
- it 'does not prefix with unique_prefix' do
40
- allow(SidekiqUniqueJobs.config).to receive(:unique_prefix).and_return(nil)
41
- expect(described_class.prefix('key')).to eq('key')
42
- end
43
+ describe '.expire' do
44
+ before do
45
+ acquire_lock
43
46
  end
44
47
 
48
+ it 'does some shit' do
49
+ sleep 1
50
+ expected = { jid => unique_key }
51
+ expect(described_class.unique_hash).to match(expected)
52
+ removed_keys = described_class.expire
53
+ expect(removed_keys).to match(expected)
54
+ expect(described_class.unique_hash).not_to match(expected)
55
+ expect(described_class.keys('*')).not_to include(unique_key)
56
+ end
57
+ end
58
+
59
+ describe '.prefix' do
45
60
  before do
46
61
  allow(SidekiqUniqueJobs.config).to receive(:unique_prefix).and_return('test-uniqueness')
47
62
  end
@@ -49,5 +64,18 @@ RSpec.describe SidekiqUniqueJobs::Util do
49
64
  it 'returns a prefixed key' do
50
65
  expect(described_class.prefix('key')).to eq('test-uniqueness:key')
51
66
  end
67
+
68
+ context 'when .unique_prefix is nil?' do
69
+ it 'does not prefix with unique_prefix' do
70
+ allow(SidekiqUniqueJobs.config).to receive(:unique_prefix).and_return(nil)
71
+ expect(described_class.prefix('key')).to eq('key')
72
+ end
73
+ end
74
+
75
+ context 'when key is already prefixed' do
76
+ it 'does not add another prefix' do
77
+ expect(described_class.prefix('test-uniqueness:key')).to eq('test-uniqueness:key')
78
+ end
79
+ end
52
80
  end
53
81
  end
@@ -20,7 +20,7 @@ require 'sidekiq_unique_jobs/testing'
20
20
  require 'sidekiq/simulator'
21
21
 
22
22
  Sidekiq::Testing.disable!
23
- Sidekiq.logger.level = "Logger::#{ENV.fetch('LOGLEVEL') { 'error' }.upcase}".constantize
23
+ SidekiqUniqueJobs.logger.level = "Logger::#{ENV.fetch('LOGLEVEL') { 'error' }.upcase}".constantize
24
24
 
25
25
  require 'sidekiq/redis_connection'
26
26
 
@@ -35,7 +35,8 @@ Sidekiq.configure_client do |config|
35
35
  end
36
36
 
37
37
  Dir[File.join(File.dirname(__FILE__), 'support', '**', '*.rb')].each { |f| require f }
38
- RSpec.configure do |config|
38
+
39
+ RSpec.configure do |config| # rubocop:disable BlockLength
39
40
  config.expect_with :rspec do |expectations|
40
41
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
41
42
  end
@@ -49,6 +50,43 @@ RSpec.configure do |config|
49
50
  config.default_formatter = 'doc' if config.files_to_run.one?
50
51
  config.order = :random
51
52
  Kernel.srand config.seed
53
+
54
+ config.before(:each) do
55
+ SidekiqUniqueJobs.configure do |unique_config|
56
+ unique_config.redis_test_mode = :redis
57
+ end
58
+ Sidekiq.redis = REDIS
59
+ Sidekiq.redis(&:flushdb)
60
+ Sidekiq::Worker.clear_all
61
+ Sidekiq::Queues.clear_all
62
+
63
+ if Sidekiq::Testing.respond_to?(:server_middleware)
64
+ Sidekiq::Testing.server_middleware do |chain|
65
+ chain.add SidekiqUniqueJobs::Server::Middleware
66
+ end
67
+ end
68
+ enable_delay = defined?(Sidekiq::Extensions) && Sidekiq::Extensions.respond_to?(:enable_delay!)
69
+ Sidekiq::Extensions.enable_delay! if enable_delay
70
+ end
71
+
72
+ config.after(:each) do
73
+ Sidekiq.redis(&:flushdb)
74
+ respond_to_middleware = defined?(Sidekiq::Testing) && Sidekiq::Testing.respond_to?(:server_middleware)
75
+ Sidekiq::Testing.server_middleware(&:clear) if respond_to_middleware
76
+ end
52
77
  end
53
78
 
54
79
  Dir[File.join(File.dirname(__FILE__), 'jobs', '**', '*.rb')].each { |f| require f }
80
+
81
+ def capture(stream)
82
+ begin
83
+ stream = stream.to_s
84
+ eval "$#{stream} = StringIO.new" # rubocop:disable Security/Eval
85
+ yield
86
+ result = eval("$#{stream}").string # rubocop:disable Security/Eval
87
+ ensure
88
+ eval("$#{stream} = #{stream.upcase}") # rubocop:disable Security/Eval
89
+ end
90
+
91
+ result
92
+ end
@@ -2,18 +2,28 @@ require 'rspec/expectations'
2
2
 
3
3
  RSpec::Matchers.define :have_key do |unique_key|
4
4
  Sidekiq.redis do |redis|
5
- match do |_actual|
6
- with_value && for_seconds
5
+ match do |_unique_jobs|
6
+ @value = redis.get(unique_key)
7
+ @ttl = redis.ttl(unique_key)
8
+
9
+ @value && with_value && for_seconds
7
10
  end
8
11
 
9
12
  chain :with_value do |value = nil|
10
- value.nil? ||
11
- redis.get(unique_key) == value
13
+ @expected_value = value
14
+ @expected_value && @value == @expected_value
12
15
  end
13
16
 
14
17
  chain :for_seconds do |ttl = nil|
15
- ttl.nil? ||
16
- redis.ttl(unique_key) == ttl
18
+ @expected_ttl = ttl
19
+ @expected_ttl && @ttl == @expected_ttl
20
+ end
21
+
22
+ failure_message do |_actual|
23
+ msg = "expected Redis to have key #{unique_key}"
24
+ msg << " with value #{@expected_value} was (#{@value})" if @expected_value
25
+ msg << " with value #{@expected_ttl} was (#{@ttl})" if @expected_ttl
26
+ msg
17
27
  end
18
28
  end
19
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-unique-jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0
4
+ version: 5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikael Henriksson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-08 00:00:00.000000000 Z
11
+ date: 2017-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: aruba
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: codeclimate-test-reporter
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -175,6 +189,8 @@ files:
175
189
  - lib/sidekiq_unique_jobs/run_lock_failed.rb
176
190
  - lib/sidekiq_unique_jobs/script_mock.rb
177
191
  - lib/sidekiq_unique_jobs/scripts.rb
192
+ - lib/sidekiq_unique_jobs/scripts/acquire_lock.rb
193
+ - lib/sidekiq_unique_jobs/scripts/release_lock.rb
178
194
  - lib/sidekiq_unique_jobs/server/middleware.rb
179
195
  - lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb
180
196
  - lib/sidekiq_unique_jobs/testing.rb
@@ -213,6 +229,7 @@ files:
213
229
  - rails_example/app/workers/simple_worker.rb
214
230
  - rails_example/app/workers/slow_until_executing_worker.rb
215
231
  - rails_example/app/workers/spawn_simple_worker.rb
232
+ - rails_example/app/workers/while_executing_worker.rb
216
233
  - rails_example/app/workers/without_argument_worker.rb
217
234
  - rails_example/bin/bundle
218
235
  - rails_example/bin/check_or_setup_db
@@ -307,6 +324,7 @@ files:
307
324
  - spec/jobs/until_timeout_job.rb
308
325
  - spec/jobs/while_executing_job.rb
309
326
  - spec/jobs/without_argument_job.rb
327
+ - spec/lib/sidekiq_unique_jobs/cli_spec.rb
310
328
  - spec/lib/sidekiq_unique_jobs/client/middleware_spec.rb
311
329
  - spec/lib/sidekiq_unique_jobs/config_spec.rb
312
330
  - spec/lib/sidekiq_unique_jobs/core_ext_spec.rb
@@ -319,6 +337,8 @@ files:
319
337
  - spec/lib/sidekiq_unique_jobs/queue_lock_timeout_calculator_spec.rb
320
338
  - spec/lib/sidekiq_unique_jobs/run_lock_timeout_calculator_spec.rb
321
339
  - spec/lib/sidekiq_unique_jobs/script_mock_spec.rb
340
+ - spec/lib/sidekiq_unique_jobs/scripts/acquire_lock_spec.rb
341
+ - spec/lib/sidekiq_unique_jobs/scripts/release_lock_spec.rb
322
342
  - spec/lib/sidekiq_unique_jobs/scripts_spec.rb
323
343
  - spec/lib/sidekiq_unique_jobs/server/middleware_spec.rb
324
344
  - spec/lib/sidekiq_unique_jobs/sidekiq_testing_enabled_spec.rb