sidekiq-unique-jobs 5.0.1 → 5.0.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.

Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +18 -0
  3. data/.simplecov +3 -1
  4. data/.travis.yml +0 -1
  5. data/README.md +3 -0
  6. data/lib/sidekiq_unique_jobs/lock/until_executed.rb +1 -1
  7. data/lib/sidekiq_unique_jobs/normalizer.rb +2 -0
  8. data/lib/sidekiq_unique_jobs/script_mock.rb +1 -1
  9. data/lib/sidekiq_unique_jobs/sidekiq_unique_ext.rb +9 -36
  10. data/lib/sidekiq_unique_jobs/testing/sidekiq_overrides.rb +2 -30
  11. data/lib/sidekiq_unique_jobs/unique_args.rb +9 -6
  12. data/lib/sidekiq_unique_jobs/util.rb +1 -1
  13. data/lib/sidekiq_unique_jobs/version.rb +1 -1
  14. data/rails_example/app/controllers/work_controller.rb +12 -0
  15. data/rails_example/app/workers/without_args_worker.rb +16 -0
  16. data/rails_example/config/routes.rb +2 -1
  17. data/spec/jobs/my_unique_job.rb +1 -1
  18. data/spec/jobs/unique_job_with_conditional_parameter.rb +14 -0
  19. data/spec/jobs/unique_job_with_nil_unique_args.rb +16 -0
  20. data/spec/jobs/unique_job_with_no_unique_args_method.rb +12 -0
  21. data/spec/jobs/unique_job_withthout_unique_args_parameter.rb +14 -0
  22. data/spec/lib/sidekiq_unique_jobs/cli_spec.rb +2 -2
  23. data/spec/lib/sidekiq_unique_jobs/client/middleware_spec.rb +4 -4
  24. data/spec/lib/sidekiq_unique_jobs/options_with_fallback_spec.rb +1 -1
  25. data/spec/lib/sidekiq_unique_jobs/scripts/acquire_lock_spec.rb +1 -1
  26. data/spec/lib/sidekiq_unique_jobs/sidekiq_unique_ext_spec.rb +1 -1
  27. data/spec/lib/sidekiq_unique_jobs/unique_args_spec.rb +122 -12
  28. data/spec/lib/sidekiq_unique_jobs/unlockable_spec.rb +1 -1
  29. data/spec/support/ruby_meta.rb +1 -1
  30. data/spec/support/sidekiq_meta.rb +1 -1
  31. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 54089588f5279692be7686eca3e9b4987c9cb706
4
- data.tar.gz: 2ce8320f727817419868df6ddc877d143c9318cf
3
+ metadata.gz: 4ca11c77223ec339ed2dba0bbfa3630c17db88df
4
+ data.tar.gz: 8ac3ea5ed96f4303663cd7a43b3b70e93ece13c5
5
5
  SHA512:
6
- metadata.gz: fe2abbb06c27ef94b8266d1bcc1727b1385e7d6897c35731986d90306ce218b16b7d22336facbfff95b43e294abf5dbe4b894ce4d6629d4373e272cb20285502
7
- data.tar.gz: eba5e89015ec74852a4a6e0615e3793ede42dee32a22e59ccd019de3a22e14b27ea27dbb757c5a4cf6cc3eab2bf80d2a6801928bb8a4030c6c3dfb45e31df593
6
+ metadata.gz: ab6f325ea2633be2150c15f9441133901ec42fa767a5777328df8c44438fab1e8eddbb674a4f11132028899f7fab6c2a19dc1541dd9e2acea257e58bb96b3aca
7
+ data.tar.gz: ece51ecdb1244507c06a5336d78106b92423b13d026d4c1f8a0ebadad778526522ce52efc7199b41530295fd2865f1732e53029ad929c51f70ef62ab944d79c3
data/.rubocop.yml CHANGED
@@ -55,10 +55,28 @@ Style/FileName:
55
55
  Style/GlobalVars:
56
56
  Enabled: true
57
57
 
58
+ Style/StringLiterals:
59
+ Enabled: true
60
+ EnforcedStyle: single_quotes
61
+ ConsistentQuotesInMultiline: true
62
+
63
+ Style/StringLiteralsInInterpolation:
64
+ Enabled: true
65
+ EnforcedStyle: single_quotes
66
+
58
67
  Style/SymbolArray:
59
68
  Enabled: true
60
69
  EnforcedStyle: brackets
61
70
 
71
+ Style/TernaryParentheses:
72
+ Enabled: true
73
+ EnforcedStyle: require_parentheses_when_complex
74
+ AllowSafeAssignment: true
75
+
76
+ Style/TrailingCommaInArguments:
77
+ Enabled: true
78
+ EnforcedStyleForMultiline: comma
79
+
62
80
  Style/TrailingCommaInLiteral:
63
81
  Enabled: true
64
82
  EnforcedStyleForMultiline: comma
data/.simplecov CHANGED
@@ -1,11 +1,13 @@
1
1
  require 'simplecov-json'
2
2
  require 'codeclimate-test-reporter'
3
3
 
4
- # SimpleCov.refuse_coverage_drop
4
+ SimpleCov.command_name 'rspec'
5
+ SimpleCov.refuse_coverage_drop
5
6
  SimpleCov.formatters = [
6
7
  SimpleCov::Formatter::HTMLFormatter,
7
8
  SimpleCov::Formatter::JSONFormatter,
8
9
  ]
10
+
9
11
  SimpleCov.start do
10
12
  add_filter '/spec/'
11
13
  add_filter '/bin/'
data/.travis.yml CHANGED
@@ -14,7 +14,6 @@ script:
14
14
  rvm:
15
15
  - 2.4.1
16
16
  - 2.3.2
17
- - 2.2.5
18
17
  - jruby-9.1.8.0
19
18
  env: STYLE=false
20
19
  gemfile:
data/README.md CHANGED
@@ -202,6 +202,9 @@ Start the console with the following command `bundle exec jobs console`.
202
202
  #### Remove Unique Keys
203
203
  `del '*', 100, false` the dry_run and count parameters are both required. This is to have some type of protection against clearing out all uniqueness.
204
204
 
205
+ #### Expire
206
+ `expire` clears the unique hash from expired keys
207
+
205
208
  ### Command Line
206
209
 
207
210
  `bundle exec jobs` displays help on how to use the unique jobs command line.
@@ -44,7 +44,7 @@ module SidekiqUniqueJobs
44
44
  redis_pool,
45
45
  unique_key,
46
46
  item[JID_KEY],
47
- max_lock_time
47
+ max_lock_time,
48
48
  )
49
49
  end
50
50
  # rubocop:enable MethodLength
@@ -1,3 +1,5 @@
1
+ require 'json'
2
+
1
3
  module SidekiqUniqueJobs
2
4
  module Normalizer
3
5
  def self.jsonify(args)
@@ -19,7 +19,7 @@ module SidekiqUniqueJobs
19
19
  expires = options[:argv][1].to_i
20
20
  stored_jid = redis.get(unique_key)
21
21
 
22
- return stored_jid == job_id ? 1 : 0 if stored_jid
22
+ return (stored_jid == job_id) ? 1 : 0 if stored_jid
23
23
 
24
24
  return 0 unless redis.set(unique_key, job_id, nx: true, ex: expires)
25
25
  redis.hsetnx(SidekiqUniqueJobs::HASH_KEY, job_id, unique_key)
@@ -14,47 +14,24 @@ module Sidekiq
14
14
  end
15
15
 
16
16
  def delete_ext
17
- unlock(item) if delete_orig
17
+ SidekiqUniqueJobs::Unlockable.unlock(item) if delete_orig
18
18
  end
19
19
 
20
20
  private
21
21
 
22
22
  def remove_job_ext
23
23
  remove_job_orig do |message|
24
- unlock(Sidekiq.load_json(message))
24
+ SidekiqUniqueJobs::Unlockable.unlock(Sidekiq.load_json(message))
25
25
  yield message
26
26
  end
27
27
  end
28
28
  end
29
29
 
30
- include UniqueExtension if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('3.1')
30
+ include UniqueExtension
31
31
  end
32
32
 
33
33
  class ScheduledSet
34
- # rubocop:disable Style/ClassAndModuleCamelCase
35
- module UniqueExtension3_0
36
- def self.included(base)
37
- base.class_eval do
38
- include SidekiqUniqueJobs::Unlockable
39
- alias_method :delete_orig, :delete
40
- alias_method :delete, :delete_ext
41
- end
42
- end
43
-
44
- def delete_ext(score, jid = nil)
45
- item = find_job(jid)
46
- unlock(item) if delete_orig(score, jid)
47
- end
48
-
49
- def remove_job_ext
50
- remove_job_orig do |message|
51
- unlock(Sidekiq.load_json(message))
52
- yield message
53
- end
54
- end
55
- end
56
-
57
- module UniqueExtension3_5
34
+ module UniqueExtension
58
35
  def self.included(base)
59
36
  base.class_eval do
60
37
  include SidekiqUniqueJobs::Unlockable
@@ -64,21 +41,17 @@ module Sidekiq
64
41
  end
65
42
 
66
43
  def delete_ext
67
- unlock(item) if delete_orig
44
+ SidekiqUniqueJobs::Unlockable.unlock(item) if delete_orig
68
45
  end
69
46
 
70
47
  def remove_job_ext
71
48
  remove_job_orig do |message|
72
- unlock(Sidekiq.load_json(message))
49
+ SidekiqUniqueJobs::Unlockable.unlock(Sidekiq.load_json(message))
73
50
  yield message
74
51
  end
75
52
  end
76
53
  end
77
- sidekiq_version = Gem::Version.new(Sidekiq::VERSION)
78
- include UniqueExtension3_5 if sidekiq_version >= Gem::Version.new('3.5')
79
- include UniqueExtension3_0 if sidekiq_version >= Gem::Version.new('3.0') &&
80
- sidekiq_version < Gem::Version.new('3.5')
81
- # rubocop:enable Style/ClassAndModuleCamelCase
54
+ include UniqueExtension
82
55
  end
83
56
 
84
57
  class Job
@@ -92,7 +65,7 @@ module Sidekiq
92
65
  end
93
66
 
94
67
  def delete_ext
95
- unlock(item)
68
+ SidekiqUniqueJobs::Unlockable.unlock(item)
96
69
  delete_orig
97
70
  end
98
71
  end
@@ -142,7 +115,7 @@ module Sidekiq
142
115
  end
143
116
 
144
117
  def delete_by_value_ext(name, value)
145
- unlock(JSON.parse(value)) if delete_by_value_orig(name, value)
118
+ SidekiqUniqueJobs::Unlockable.unlock(JSON.parse(value)) if delete_by_value_orig(name, value)
146
119
  end
147
120
  end
148
121
 
@@ -3,42 +3,14 @@ require 'sidekiq/testing'
3
3
  module Sidekiq
4
4
  module Worker
5
5
  module ClassMethods
6
- # Drain and run all jobs for this worker
7
- unless Sidekiq::Testing.respond_to?(:server_middleware)
8
- def drain
9
- while (job = jobs.shift)
10
- worker = new
11
- worker.jid = job['jid']
12
- worker.bid = job['bid'] if worker.respond_to?(:bid=)
13
- execute_job(worker, job['args'])
14
- unlock(job) if Sidekiq::Testing.fake?
15
- end
16
- end
17
- end
18
-
19
- # Pop out a single job and perform it
20
- unless Sidekiq::Testing.respond_to?(:server_middleware)
21
- def perform_one
22
- raise(EmptyQueueError, 'perform_one called with empty job queue') if jobs.empty?
23
- job = jobs.shift
24
- worker = new
25
- worker.jid = job['jid']
26
- worker.bid = job['bid'] if worker.respond_to?(:bid=)
27
- execute_job(worker, job['args'])
28
- unlock(job) if Sidekiq::Testing.fake?
29
- end
30
- end
31
-
32
6
  # Clear all jobs for this worker
33
7
  def clear
34
8
  jobs.each do |job|
35
9
  unlock(job) if Sidekiq::Testing.fake?
36
10
  end
37
- # if Sidekiq::VERSION >= '4'
38
- # Queues.jobs[queue].clear
39
- # else
11
+
12
+ Sidekiq::Queues[queue].clear
40
13
  jobs.clear
41
- # end
42
14
  end
43
15
 
44
16
  unless respond_to?(:execute_job)
@@ -45,7 +45,7 @@ module SidekiqUniqueJobs
45
45
 
46
46
  if unique_on_all_queues?
47
47
  logger.debug do
48
- "uniqueness specified across all queues (deleting queue: #{@item[QUEUE_KEY]} from hash)"
48
+ "#{__method__} uniqueness specified across all queues (deleting queue: #{@item[QUEUE_KEY]} from hash)"
49
49
  end
50
50
  hash.delete(QUEUE_KEY)
51
51
  end
@@ -78,7 +78,7 @@ module SidekiqUniqueJobs
78
78
  if @worker_class.respond_to?(:get_sidekiq_options)
79
79
  true
80
80
  else
81
- logger.debug { "#{@worker_class} does not respond to :get_sidekiq_options" }
81
+ logger.debug { "#{__method__} #{@worker_class} does not respond to :get_sidekiq_options" }
82
82
  nil
83
83
  end
84
84
  end
@@ -96,14 +96,14 @@ module SidekiqUniqueJobs
96
96
  when Symbol
97
97
  filter_by_symbol(json_args)
98
98
  else
99
- logger.debug { 'arguments not filtered (the combined arguments count towards uniqueness)' }
99
+ logger.debug { "#{__method__} arguments not filtered (using all arguments for uniqueness)" }
100
100
  json_args
101
101
  end
102
102
  end
103
103
 
104
104
  def filter_by_proc(args)
105
105
  if unique_args_method.nil?
106
- warn { "#{__method__} : Proc was nil, returning args as is #{args} -> #{filter_args}" }
106
+ logger.warn { "#{__method__} : unique_args_method is nil. Returning (#{args})" }
107
107
  return args
108
108
  end
109
109
  filter_args = unique_args_method.call(args)
@@ -114,8 +114,7 @@ module SidekiqUniqueJobs
114
114
  def filter_by_symbol(args)
115
115
  unless @worker_class.respond_to?(unique_args_method)
116
116
  logger.warn do
117
- "#{__method__} : #{unique_args_method}) not defined in #{@worker_class} " \
118
- "returning #{args} unchanged"
117
+ "#{__method__} : #{@worker_class} does not respond to #{unique_args_method}). Returning (#{args})"
119
118
  end
120
119
  return args
121
120
  end
@@ -123,6 +122,10 @@ module SidekiqUniqueJobs
123
122
  filter_args = @worker_class.send(unique_args_method, args)
124
123
  logger.debug { "#{__method__} : #{unique_args_method}(#{args}) => #{filter_args}" }
125
124
  filter_args
125
+ rescue ArgumentError => ex
126
+ logger.fatal "#{__method__} : #{@worker_class}'s #{unique_args_method} needs at least one argument"
127
+ logger.fatal ex
128
+ args
126
129
  end
127
130
 
128
131
  def unique_args_method
@@ -107,7 +107,7 @@ module SidekiqUniqueJobs
107
107
  end
108
108
 
109
109
  def redis_keys_method
110
- redis_version >= '2.8' ? SCAN_METHOD : KEYS_METHOD
110
+ (redis_version >= '2.8') ? SCAN_METHOD : KEYS_METHOD
111
111
  end
112
112
 
113
113
  def logger
@@ -1,3 +1,3 @@
1
1
  module SidekiqUniqueJobs
2
- VERSION = '5.0.1'.freeze
2
+ VERSION = '5.0.2'.freeze
3
3
  end
@@ -17,6 +17,18 @@ class WorkController < ApplicationController
17
17
  redirect_to '/sidekiq'
18
18
  end
19
19
 
20
+ def duplicate_without_args
21
+ 4.times { WithoutArgsWorker.perform_async }
22
+
23
+ redirect_to '/sidekiq'
24
+ end
25
+
26
+ def duplicate_with_args
27
+ 4.times { WithoutArgsWorker.perform_async 1 }
28
+
29
+ redirect_to '/sidekiq'
30
+ end
31
+
20
32
  def unique_argument
21
33
  params[:id]
22
34
  end
@@ -0,0 +1,16 @@
1
+ class WithoutArgsWorker
2
+ include Sidekiq::Worker
3
+ sidekiq_options queue: :default,
4
+ retry: true,
5
+ backtrace: true,
6
+ unique: :until_executed,
7
+ unique_args: :custom_args
8
+
9
+ def perform(_conditional = nil)
10
+ sleep 2
11
+ end
12
+
13
+ def self.custom_args
14
+ puts 'testing'
15
+ end
16
+ end
@@ -3,5 +3,6 @@ Rails.application.routes.draw do
3
3
  mount Sidekiq::Web, at: '/sidekiq'
4
4
  get 'work/duplicate_simple' => 'work#duplicate_simple'
5
5
  get 'work/duplicate_nested' => 'work#duplicate_nested'
6
- get 'work/duplicate_slow' => 'work#duplicate_slow'
6
+ get 'work/duplicate_without_args' => 'work#duplicate_without_args'
7
+ get 'work/duplicate_with_args' => 'work#duplicate_with_args'
7
8
  end
@@ -5,7 +5,7 @@ class MyUniqueJob
5
5
  retry: true,
6
6
  unique: :until_executed,
7
7
  unique_expiration: 7_200,
8
- retry_count: 10
8
+ retry_count: 10,
9
9
  )
10
10
  def perform(_one, _two); end
11
11
  end
@@ -0,0 +1,14 @@
1
+ class UniqueJobWithoutUniqueArgsParameter
2
+ include Sidekiq::Worker
3
+ sidekiq_options queue: :customqueue,
4
+ retry: true,
5
+ backtrace: true,
6
+ unique: :until_executed,
7
+ unique_args: :unique_args
8
+
9
+ def perform(conditional = nil)
10
+ # NO-OP
11
+ end
12
+
13
+ def self.unique_args; end
14
+ end
@@ -0,0 +1,16 @@
1
+ class UniqueJobWithNilUniqueArgs
2
+ include Sidekiq::Worker
3
+ sidekiq_options queue: :customqueue,
4
+ retry: true,
5
+ backtrace: true,
6
+ unique: :until_executed,
7
+ unique_args: :unique_args
8
+
9
+ def perform(*)
10
+ # NO-OP
11
+ end
12
+
13
+ def self.unique_args(_args)
14
+ nil
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ class UniqueJobWithNoUniqueArgsMethod
2
+ include Sidekiq::Worker
3
+ sidekiq_options queue: :customqueue,
4
+ retry: true,
5
+ backtrace: true,
6
+ unique: :until_executed,
7
+ unique_args: :filtered_args
8
+
9
+ def perform(*)
10
+ # NO-OP
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ class UniqueJobWithoutUniqueArgsParameter
2
+ include Sidekiq::Worker
3
+ sidekiq_options queue: :customqueue,
4
+ retry: true,
5
+ backtrace: true,
6
+ unique: :until_executed,
7
+ unique_args: :unique_args
8
+
9
+ def perform(optional = true)
10
+ # NO-OP
11
+ end
12
+
13
+ def self.unique_args; end
14
+ end
@@ -108,8 +108,8 @@ RSpec.describe SidekiqUniqueJobs::Cli, ruby_ver: '>= 2.4' do
108
108
 
109
109
  let(:expected) do
110
110
  <<~EOS
111
- Found 3 keys matching '#{pattern}':
112
- uniquejobs:abcdefab uniquejobs:defghayl uniquejobs:poilkij
111
+ Found 3 keys matching '#{pattern}':
112
+ uniquejobs:abcdefab uniquejobs:defghayl uniquejobs:poilkij
113
113
  EOS
114
114
  end
115
115
  specify do
@@ -123,7 +123,7 @@ RSpec.describe SidekiqUniqueJobs::Client::Middleware do
123
123
  Sidekiq::Client.push(
124
124
  'class' => MyUniqueJobWithFilterProc,
125
125
  'queue' => 'customqueue',
126
- 'args' => [1, type: 'value', some: 'not used']
126
+ 'args' => [1, type: 'value', some: 'not used'],
127
127
  )
128
128
  end
129
129
  Sidekiq.redis { |c| expect(c.llen('queue:customqueue')).to eq(1) }
@@ -140,7 +140,7 @@ RSpec.describe SidekiqUniqueJobs::Client::Middleware do
140
140
  Sidekiq::Client.push(
141
141
  'class' => MyUniqueJobWithFilterMethod,
142
142
  'queue' => 'customqueue',
143
- 'args' => [1, type: 'value', some: 'not used']
143
+ 'args' => [1, type: 'value', some: 'not used'],
144
144
  )
145
145
  end
146
146
  Sidekiq.redis { |c| expect(c.llen('queue:customqueue')).to eq(1) }
@@ -212,7 +212,7 @@ RSpec.describe SidekiqUniqueJobs::Client::Middleware do
212
212
  Sidekiq::Client.push(
213
213
  'class' => CustomQueueJobWithFilterMethod,
214
214
  'queue' => 'customqueue',
215
- 'args' => [1, i]
215
+ 'args' => [1, i],
216
216
  )
217
217
  end
218
218
 
@@ -228,7 +228,7 @@ RSpec.describe SidekiqUniqueJobs::Client::Middleware do
228
228
  Sidekiq::Client.push(
229
229
  'class' => CustomQueueJobWithFilterProc,
230
230
  'queue' => 'customqueue',
231
- 'args' => [1, { random: rand, name: 'foobar' }]
231
+ 'args' => [1, { random: rand, name: 'foobar' }],
232
232
  )
233
233
  end
234
234
 
@@ -13,7 +13,7 @@ RSpec.describe SidekiqUniqueJobs::OptionsWithFallback do
13
13
  .to receive(:warn)
14
14
  .with(
15
15
  'unique: true is no longer valid. Please set it to the type of lock required like: ' \
16
- '`unique: :until_executed`'
16
+ '`unique: :until_executed`',
17
17
  )
18
18
 
19
19
  subject.unique_lock
@@ -26,7 +26,7 @@ RSpec.describe SidekiqUniqueJobs::Scripts::AcquireLock do
26
26
  redis_pool,
27
27
  key,
28
28
  myjid,
29
- max_lock
29
+ max_lock,
30
30
  )
31
31
  end
32
32
 
@@ -17,7 +17,7 @@ RSpec.describe 'Sidekiq::Api' do
17
17
  'class' => JustAWorker,
18
18
  'queue' => 'testqueue',
19
19
  'args' => [foo: 'bar'],
20
- 'at' => (Date.today + 1).to_time.to_i
20
+ 'at' => (Date.today + 1).to_time.to_i,
21
21
  )
22
22
  end
23
23
 
@@ -3,7 +3,6 @@ require 'spec_helper'
3
3
  RSpec.describe SidekiqUniqueJobs::UniqueArgs do
4
4
  let(:item) { { 'class' => 'UntilExecutedJob', 'queue' => 'myqueue', 'args' => [[1, 2]] } }
5
5
  subject { described_class.new(item) }
6
-
7
6
  describe '#unique_digest' do
8
7
  context 'when args are empty' do
9
8
  let(:item) { { 'class' => 'WithoutArgumentJob', 'args' => [] } }
@@ -114,34 +113,145 @@ RSpec.describe SidekiqUniqueJobs::UniqueArgs do
114
113
 
115
114
  describe '#filter_by_proc' do
116
115
  let(:filter) { ->(args) { args[1]['test'] } }
116
+ let(:args) { [1, 'test' => 'it'] }
117
+ let(:unique_args) { described_class.new(item) }
118
+
119
+ subject { unique_args.filter_by_proc(args) }
120
+
117
121
  context 'without any default worker options configured' do
118
122
  before do
119
- allow(subject).to receive(:unique_args_method).and_return(filter)
123
+ allow(unique_args).to receive(:unique_args_method).and_return(filter)
124
+ end
125
+
126
+ it 'returns the value of theoptions hash ' do
127
+ expect(subject).to eq('it')
128
+ end
129
+ end
130
+
131
+ context 'when #unique_args_method is nil' do
132
+ before do
133
+ allow(unique_args).to receive(:unique_args_method).and_return(nil)
120
134
  end
121
135
 
122
136
  it 'returns the value of theoptions hash ' do
123
- expect(subject.filter_by_proc([1, 'test' => 'it'])).to eq('it')
137
+ expect(SidekiqUniqueJobs.logger).to receive(:warn) do |&block|
138
+ expect(block.call).to eq('filter_by_proc : unique_args_method is nil. Returning ([1, {"test"=>"it"}])')
139
+ end
140
+ expect(subject).to eq(args)
124
141
  end
125
142
  end
126
143
 
127
144
  with_default_worker_options(unique: :until_executed, unique_args: ->(args) { args[1]['test'] }) do
128
145
  it 'returns the value of the provided options' do
129
- expect(subject.filter_by_proc([1, 'test' => 'it'])).to eq('it')
146
+ expect(subject).to eq('it')
130
147
  end
131
148
  end
132
149
  end
133
150
 
134
151
  describe '#filter_by_symbol' do
135
- let(:item) do
136
- { 'class' => 'UniqueJobWithFilterMethod',
137
- 'queue' => 'myqueue',
138
- 'args' => [[1, 2]] }
152
+ let(:unique_args) { described_class.new(item) }
153
+
154
+ context 'when filter is a working symbol' do
155
+ let(:item) do
156
+ { 'class' => 'UniqueJobWithFilterMethod',
157
+ 'queue' => 'myqueue',
158
+ 'args' => [[1, 2]] }
159
+ end
160
+
161
+ let(:args) { ['name', 2, 'whatever' => nil, 'type' => 'test'] }
162
+ subject { unique_args.filter_by_symbol(args) }
163
+
164
+ it 'returns the value of the provided class method' do
165
+ expected = %w[name test]
166
+ expect(unique_args.logger).to receive(:debug) do |&block|
167
+ expect(block.call).to eq("filter_by_symbol : filtered_args(#{args}) => #{expected}")
168
+ end
169
+ expect(subject).to eq(expected)
170
+ end
139
171
  end
140
- subject { described_class.new(item) }
141
172
 
142
- it 'returns the value of the provided class method' do
143
- expect(subject.filter_by_symbol(['name', 2, 'whatever' => nil, 'type' => 'test']))
144
- .to eq(%w[name test])
173
+ context 'when worker takes conditional parameters' do
174
+ let(:item) do
175
+ { 'class' => 'UniqueJobWithoutUniqueArgsParameter',
176
+ 'queue' => 'myqueue',
177
+ 'args' => [1] }
178
+ end
179
+ let(:args) { [1] }
180
+
181
+ subject { unique_args.filter_by_symbol(args) }
182
+
183
+ it 'returns the value of the provided class method' do
184
+ expect(subject).to eq(args)
185
+ end
186
+
187
+ context 'when provided nil' do
188
+ let(:args) { [] }
189
+ it 'returns the value of the provided class method' do
190
+ expect(subject).to eq(args)
191
+ end
192
+ end
193
+ end
194
+
195
+ context "when workers unique_args method doesn't take parameters" do
196
+ let(:item) do
197
+ { 'class' => 'UniqueJobWithoutUniqueArgsParameter',
198
+ 'queue' => 'myqueue',
199
+ 'args' => [[1, 2]] }
200
+ end
201
+
202
+ let(:args) { ['name', 2, 'whatever' => nil, 'type' => 'test'] }
203
+ subject { unique_args.filter_by_symbol(args) }
204
+
205
+ it 'returns the value of the provided class method' do
206
+ expect(unique_args.logger)
207
+ .to receive(:fatal)
208
+ .with('filter_by_symbol : UniqueJobWithoutUniqueArgsParameter\'s unique_args needs at least one argument')
209
+ expect(unique_args.logger).to receive(:fatal).with a_kind_of(ArgumentError)
210
+
211
+ expect(subject).to eq(args)
212
+ end
213
+ end
214
+
215
+ context 'when @worker_class does not respond_to unique_args_method' do
216
+ let(:item) do
217
+ { 'class' => 'UniqueJobWithNoUniqueArgsMethod',
218
+ 'queue' => 'myqueue',
219
+ 'args' => [[1, 2]] }
220
+ end
221
+
222
+ let(:args) { ['name', 2, 'whatever' => nil, 'type' => 'test'] }
223
+ subject { unique_args.filter_by_symbol(args) }
224
+
225
+ it 'returns the value of the provided class method' do
226
+ expect(unique_args.logger).to receive(:warn) do |&block|
227
+ expect(block.call)
228
+ .to eq(
229
+ "filter_by_symbol : UniqueJobWithNoUniqueArgsMethod does not respond to filtered_args). " \
230
+ "Returning (#{args})",
231
+ )
232
+ end
233
+
234
+ expect(subject).to eq(args)
235
+ end
236
+ end
237
+
238
+ context 'when workers unique_args method returns nil' do
239
+ let(:item) do
240
+ { 'class' => 'UniqueJobWithNilUniqueArgs',
241
+ 'queue' => 'myqueue',
242
+ 'args' => [[1, 2]] }
243
+ end
244
+
245
+ let(:args) { ['name', 2, 'whatever' => nil, 'type' => 'test'] }
246
+ subject { unique_args.filter_by_symbol(args) }
247
+
248
+ it 'returns the value of the provided class method' do
249
+ expect(unique_args.logger).to receive(:debug) do |&block|
250
+ expect(block.call).to eq("filter_by_symbol : unique_args(#{args}) => ")
251
+ end
252
+
253
+ expect(subject).to eq(nil)
254
+ end
145
255
  end
146
256
  end
147
257
  end
@@ -26,7 +26,7 @@ RSpec.describe SidekiqUniqueJobs::Unlockable do
26
26
 
27
27
  described_class.unlock_by_key(
28
28
  unique_digest,
29
- jid
29
+ jid,
30
30
  )
31
31
 
32
32
  expect(SidekiqUniqueJobs::Util.keys.count).to eq(0)
@@ -9,7 +9,7 @@ RSpec.configure do |config|
9
9
  raise 'Please specify how to compare the version with >= or < or =' unless operator
10
10
 
11
11
  unless RUBY_VERSION.send(operator, version)
12
- skip('Skipped due to version check (requirement was that ruby version is ' \
12
+ skip("Skipped due to version check (requirement was that ruby version is " \
13
13
  "#{operator} #{version}; was #{RUBY_VERSION})")
14
14
  end
15
15
  end
@@ -17,7 +17,7 @@ RSpec.configure do |config|
17
17
  raise 'Please specify how to compare the version with >= or < or =' unless operator
18
18
 
19
19
  unless Sidekiq::VERSION.send(operator, version)
20
- skip('Skipped due to version check (requirement was that sidekiq version is ' \
20
+ skip("Skipped due to version check (requirement was that sidekiq version is " \
21
21
  "#{operator} #{version}; was #{Sidekiq::VERSION})")
22
22
  end
23
23
  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.1
4
+ version: 5.0.2
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-16 00:00:00.000000000 Z
11
+ date: 2017-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -230,6 +230,7 @@ files:
230
230
  - rails_example/app/workers/slow_until_executing_worker.rb
231
231
  - rails_example/app/workers/spawn_simple_worker.rb
232
232
  - rails_example/app/workers/while_executing_worker.rb
233
+ - rails_example/app/workers/without_args_worker.rb
233
234
  - rails_example/app/workers/without_argument_worker.rb
234
235
  - rails_example/bin/bundle
235
236
  - rails_example/bin/check_or_setup_db
@@ -315,7 +316,11 @@ files:
315
316
  - spec/jobs/simple_worker.rb
316
317
  - spec/jobs/spawn_simple_worker.rb
317
318
  - spec/jobs/test_class.rb
319
+ - spec/jobs/unique_job_with_conditional_parameter.rb
318
320
  - spec/jobs/unique_job_with_filter_method.rb
321
+ - spec/jobs/unique_job_with_nil_unique_args.rb
322
+ - spec/jobs/unique_job_with_no_unique_args_method.rb
323
+ - spec/jobs/unique_job_withthout_unique_args_parameter.rb
319
324
  - spec/jobs/unique_on_all_queues_job.rb
320
325
  - spec/jobs/until_and_while_executing_job.rb
321
326
  - spec/jobs/until_executed_job.rb