sidekiq-unique-jobs 4.0.18 → 5.0.0

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +42 -7
  3. data/.csslintrc +2 -0
  4. data/.eslintignore +1 -0
  5. data/.eslintrc +213 -0
  6. data/.gitignore +2 -0
  7. data/.rspec +1 -2
  8. data/.rubocop.yml +19 -0
  9. data/.simplecov +2 -1
  10. data/.travis.yml +8 -12
  11. data/Appraisals +10 -20
  12. data/CHANGELOG.md +4 -0
  13. data/Gemfile +10 -6
  14. data/README.md +16 -2
  15. data/Rakefile +1 -0
  16. data/bin/bench +1 -0
  17. data/bin/jobs +1 -0
  18. data/circle.yml +6 -3
  19. data/gemfiles/sidekiq_4.0.gemfile +8 -5
  20. data/gemfiles/sidekiq_4.1.gemfile +8 -5
  21. data/gemfiles/{sidekiq_3.1.gemfile → sidekiq_4.2.gemfile} +9 -6
  22. data/gemfiles/{sidekiq_3.2.gemfile → sidekiq_5.0.gemfile} +9 -6
  23. data/gemfiles/sidekiq_develop.gemfile +8 -5
  24. data/lib/sidekiq-unique-jobs.rb +1 -1
  25. data/lib/sidekiq_unique_jobs/config.rb +1 -9
  26. data/lib/sidekiq_unique_jobs/constants.rb +1 -0
  27. data/lib/sidekiq_unique_jobs/core_ext.rb +44 -34
  28. data/lib/sidekiq_unique_jobs/lock/while_executing.rb +1 -1
  29. data/lib/sidekiq_unique_jobs/script_mock.rb +4 -7
  30. data/lib/sidekiq_unique_jobs/scripts.rb +9 -8
  31. data/lib/sidekiq_unique_jobs/testing/sidekiq_overrides.rb +23 -17
  32. data/lib/sidekiq_unique_jobs/unique_args.rb +1 -1
  33. data/lib/sidekiq_unique_jobs/unlockable.rb +8 -15
  34. data/lib/sidekiq_unique_jobs/util.rb +7 -0
  35. data/lib/sidekiq_unique_jobs/version.rb +1 -1
  36. data/rails_example/.env.test +12 -0
  37. data/rails_example/.rspec +1 -1
  38. data/rails_example/Gemfile +12 -9
  39. data/rails_example/app/controllers/work_controller.rb +16 -2
  40. data/rails_example/app/models/guest.rb +8 -11
  41. data/rails_example/app/workers/simple_worker.rb +4 -1
  42. data/rails_example/app/workers/slow_until_executing_worker.rb +15 -0
  43. data/rails_example/app/workers/spawn_simple_worker.rb +3 -0
  44. data/rails_example/app/workers/without_argument_worker.rb +12 -0
  45. data/rails_example/bin/check_or_setup_db +0 -1
  46. data/rails_example/common-services.yml +2 -0
  47. data/rails_example/config/database.yml +2 -2
  48. data/rails_example/config/environments/development.rb +1 -1
  49. data/rails_example/config/environments/test.rb +1 -1
  50. data/rails_example/config/initializers/sidekiq.rb +1 -1
  51. data/rails_example/config/routes.rb +1 -0
  52. data/rails_example/config/spring.rb +2 -2
  53. data/rails_example/docker-compose.yml +19 -38
  54. data/rails_example/spec/controllers/work_controller_mock_spec.rb +91 -0
  55. data/rails_example/spec/controllers/work_controller_spec.rb +46 -141
  56. data/rails_example/spec/rails_helper.rb +1 -2
  57. data/sidekiq-unique-jobs.gemspec +6 -4
  58. data/spec/jobs/custom_queue_job.rb +1 -2
  59. data/spec/jobs/just_a_worker.rb +1 -2
  60. data/spec/jobs/long_running_job.rb +1 -2
  61. data/spec/jobs/main_job.rb +1 -2
  62. data/spec/jobs/my_unique_job.rb +1 -2
  63. data/spec/jobs/plain_class.rb +1 -2
  64. data/spec/jobs/test_class.rb +1 -2
  65. data/spec/jobs/until_and_while_executing_job.rb +1 -2
  66. data/spec/jobs/until_executing_job.rb +1 -2
  67. data/spec/jobs/without_argument_job.rb +9 -0
  68. data/spec/lib/sidekiq_unique_jobs/client/middleware_spec.rb +6 -3
  69. data/spec/lib/sidekiq_unique_jobs/config_spec.rb +84 -0
  70. data/spec/lib/sidekiq_unique_jobs/lock/until_and_while_executing_spec.rb +2 -1
  71. data/spec/lib/sidekiq_unique_jobs/lock/while_executing_spec.rb +2 -2
  72. data/spec/lib/sidekiq_unique_jobs/script_mock_spec.rb +12 -6
  73. data/spec/lib/sidekiq_unique_jobs/scripts_spec.rb +0 -5
  74. data/spec/lib/sidekiq_unique_jobs/sidekiq_testing_enabled_spec.rb +5 -3
  75. data/spec/lib/sidekiq_unique_jobs/sidekiq_unique_ext_spec.rb +2 -2
  76. data/spec/lib/sidekiq_unique_jobs/unique_args_spec.rb +23 -7
  77. data/spec/lib/sidekiq_unique_jobs/unlockable_spec.rb +34 -0
  78. data/spec/lib/sidekiq_unique_jobs/util_spec.rb +1 -1
  79. data/spec/spec_helper.rb +3 -14
  80. data/spec/support/ruby_meta.rb +10 -3
  81. data/spec/support/sidekiq_meta.rb +2 -3
  82. metadata +33 -16
  83. data/gemfiles/sidekiq_2.15.gemfile +0 -9
  84. data/gemfiles/sidekiq_2.16.gemfile +0 -9
  85. data/gemfiles/sidekiq_2.17.gemfile +0 -19
  86. data/gemfiles/sidekiq_3.0.gemfile +0 -19
  87. data/gemfiles/sidekiq_3.3.gemfile +0 -19
  88. data/spec/celluloid_with_fallback.rb +0 -18
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## v5.0.0
2
+
3
+ - Only support Sidekiq >= 4
4
+
1
5
  ## v4.0.18
2
6
 
3
7
  - Allow mock_redis to be used over redis
data/Gemfile CHANGED
@@ -1,16 +1,20 @@
1
- source 'http://rubygems.org'
1
+ # rubocop:disable Style/FileName
2
+
3
+ source 'https://rubygems.org'
2
4
  gemspec
3
5
 
4
6
  gem 'appraisal', '~> 2.0.0'
5
7
  gem 'rspec-its', require: false
6
8
  gem 'rspec-wait', require: false
7
- gem 'mock_redis', require: false
8
9
 
9
- platforms :mri_23 do
10
- gem 'fasterer', require: false
10
+ platforms :mri_24 do
11
11
  gem 'benchmark-ips', require: false
12
+ gem 'codeclimate-test-reporter', require: false
13
+ gem 'fasterer', require: false
14
+ gem 'memory_profiler', require: false
15
+ gem 'mock_redis', require: false
12
16
  gem 'pry-byebug', require: false
17
+ gem 'rubocop', require: false
13
18
  gem 'simplecov-json', require: false
14
- gem 'memory_profiler', require: false
15
- gem 'codeclimate-test-reporter', require: false
19
+ gem 'travis', require: false
16
20
  end
data/README.md CHANGED
@@ -123,7 +123,7 @@ Requiring the gem in your gemfile should be sufficient to enable unique jobs.
123
123
  ```ruby
124
124
  Sidekiq.default_worker_options = {
125
125
  unique: :until_executing,
126
- unique_args: ->(args) { args.first.except('job_id') }
126
+ unique_args: ->(args) { [ args.first.except('job_id') ] }
127
127
  }
128
128
  ```
129
129
 
@@ -139,7 +139,7 @@ The method or the proc can return a modified version of args without the transie
139
139
  ```ruby
140
140
  class UniqueJobWithFilterMethod
141
141
  include Sidekiq::Worker
142
- sidekiq_options unique: :until_and_during_execution,
142
+ sidekiq_options unique: :until_and_while_execution,
143
143
  unique_args: :unique_args
144
144
 
145
145
  def self.unique_args(name, id, options)
@@ -222,6 +222,20 @@ You can if you want use `gem 'mock_redis'` to prevent sidekiq unique jobs using
222
222
 
223
223
  See https://github.com/mhenrixon/sidekiq-unique-jobs/tree/master/rails_example/spec/controllers/work_controller_spec.rb for an example of how to configure sidekiq and unique jobs without redis.
224
224
 
225
+ If you really don't care about testing uniquness and trust we get that stuff right you can (in newer sidekiq versions) remove the client middleware.
226
+
227
+ ```ruby
228
+ describe "Some test" do
229
+ before(:each) do
230
+ Sidekiq.configure_client do |config|
231
+ config.client_middleware do |chain|
232
+ chain.remove SidekiqUniqueJobs::Client::Middleware
233
+ end
234
+ end
235
+ end
236
+ end
237
+ ```
238
+
225
239
  ## Contributing
226
240
 
227
241
  1. Fork it
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env rake
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'rubygems'
4
5
  require 'bundler/setup'
data/bin/bench CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # Trap interrupts to quit cleanly. See
4
5
  # https://twitter.com/mitchellh/status/283014103189053442
data/bin/jobs CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'sidekiq-unique-jobs'
data/circle.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  machine:
2
2
  ruby:
3
3
  version:
4
- 2.2.3
4
+ 2.3.0
5
5
  java:
6
6
  version: oraclejdk8
7
7
  environment:
@@ -14,19 +14,21 @@ dependencies:
14
14
  - rvm install rbx-2
15
15
  - rvm install 2.0.0
16
16
  - rvm install 2.1.7
17
+ - rvm install 2.2.3
17
18
  override:
18
19
  - rvm-exec jruby-9.0.0.0 bundle install
19
20
  - rvm-exec jruby-1.7 bundle install
20
21
  - rvm-exec rbx-2 bundle install
21
22
  - rvm-exec 2.0.0 bundle install
22
- - rvm-exec 2.1.7 bundle install
23
- - rvm-exec 2.2.3 bundle install
23
+ - rvm-exec 2.1.8 bundle install
24
+ - rvm-exec 2.2.4 bundle install
24
25
  - rvm-exec jruby-9.0.0.0 bundle exec appraisal install
25
26
  - rvm-exec jruby-1.7 bundle exec appraisal install
26
27
  - rvm-exec rbx-2 bundle exec appraisal install
27
28
  - rvm-exec 2.0.0 bundle exec appraisal install
28
29
  - rvm-exec 2.1.7 bundle exec appraisal install
29
30
  - rvm-exec 2.2.3 bundle exec appraisal install
31
+ - rvm-exec 2.3.0 bundle exec appraisal install
30
32
 
31
33
  test:
32
34
  override:
@@ -36,3 +38,4 @@ test:
36
38
  - rvm-exec 2.0.0 bundle exec appraisal rspec
37
39
  - rvm-exec 2.1.7 bundle exec appraisal rspec
38
40
  - rvm-exec 2.2.3 bundle exec appraisal rspec
41
+ - rvm-exec 2.3.0 bundle exec appraisal rspec
@@ -1,19 +1,22 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal", "~> 2.0.0"
6
6
  gem "rspec-its", :require => false
7
7
  gem "rspec-wait", :require => false
8
8
  gem "sidekiq", "~> 4.0.0"
9
9
 
10
- platforms :mri_23 do
11
- gem "fasterer", :require => false
10
+ platforms :mri_24 do
12
11
  gem "benchmark-ips", :require => false
12
+ gem "codeclimate-test-reporter", :require => false
13
+ gem "fasterer", :require => false
14
+ gem "memory_profiler", :require => false
15
+ gem "mock_redis", :require => false
13
16
  gem "pry-byebug", :require => false
17
+ gem "rubocop", :require => false
14
18
  gem "simplecov-json", :require => false
15
- gem "memory_profiler", :require => false
16
- gem "codeclimate-test-reporter", :require => false
19
+ gem "travis", :require => false
17
20
  end
18
21
 
19
22
  gemspec :path => "../"
@@ -1,19 +1,22 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal", "~> 2.0.0"
6
6
  gem "rspec-its", :require => false
7
7
  gem "rspec-wait", :require => false
8
8
  gem "sidekiq", "~> 4.1.0"
9
9
 
10
- platforms :mri_23 do
11
- gem "fasterer", :require => false
10
+ platforms :mri_24 do
12
11
  gem "benchmark-ips", :require => false
12
+ gem "codeclimate-test-reporter", :require => false
13
+ gem "fasterer", :require => false
14
+ gem "memory_profiler", :require => false
15
+ gem "mock_redis", :require => false
13
16
  gem "pry-byebug", :require => false
17
+ gem "rubocop", :require => false
14
18
  gem "simplecov-json", :require => false
15
- gem "memory_profiler", :require => false
16
- gem "codeclimate-test-reporter", :require => false
19
+ gem "travis", :require => false
17
20
  end
18
21
 
19
22
  gemspec :path => "../"
@@ -1,19 +1,22 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal", "~> 2.0.0"
6
6
  gem "rspec-its", :require => false
7
7
  gem "rspec-wait", :require => false
8
- gem "sidekiq", "~> 3.1.0"
8
+ gem "sidekiq", "~> 4.2.0"
9
9
 
10
- platforms :mri_23 do
11
- gem "fasterer", :require => false
10
+ platforms :mri_24 do
12
11
  gem "benchmark-ips", :require => false
12
+ gem "codeclimate-test-reporter", :require => false
13
+ gem "fasterer", :require => false
14
+ gem "memory_profiler", :require => false
15
+ gem "mock_redis", :require => false
13
16
  gem "pry-byebug", :require => false
17
+ gem "rubocop", :require => false
14
18
  gem "simplecov-json", :require => false
15
- gem "memory_profiler", :require => false
16
- gem "codeclimate-test-reporter", :require => false
19
+ gem "travis", :require => false
17
20
  end
18
21
 
19
22
  gemspec :path => "../"
@@ -1,19 +1,22 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal", "~> 2.0.0"
6
6
  gem "rspec-its", :require => false
7
7
  gem "rspec-wait", :require => false
8
- gem "sidekiq", "~> 3.2.0"
8
+ gem "sidekiq", ">= 5.0.0.beta", "< 6"
9
9
 
10
- platforms :mri_23 do
11
- gem "fasterer", :require => false
10
+ platforms :mri_24 do
12
11
  gem "benchmark-ips", :require => false
12
+ gem "codeclimate-test-reporter", :require => false
13
+ gem "fasterer", :require => false
14
+ gem "memory_profiler", :require => false
15
+ gem "mock_redis", :require => false
13
16
  gem "pry-byebug", :require => false
17
+ gem "rubocop", :require => false
14
18
  gem "simplecov-json", :require => false
15
- gem "memory_profiler", :require => false
16
- gem "codeclimate-test-reporter", :require => false
19
+ gem "travis", :require => false
17
20
  end
18
21
 
19
22
  gemspec :path => "../"
@@ -1,19 +1,22 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "http://rubygems.org"
3
+ source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal", "~> 2.0.0"
6
6
  gem "rspec-its", :require => false
7
7
  gem "rspec-wait", :require => false
8
8
  gem "sidekiq", :github => "mperham/sidekiq"
9
9
 
10
- platforms :mri_23 do
11
- gem "fasterer", :require => false
10
+ platforms :mri_24 do
12
11
  gem "benchmark-ips", :require => false
12
+ gem "codeclimate-test-reporter", :require => false
13
+ gem "fasterer", :require => false
14
+ gem "memory_profiler", :require => false
15
+ gem "mock_redis", :require => false
13
16
  gem "pry-byebug", :require => false
17
+ gem "rubocop", :require => false
14
18
  gem "simplecov-json", :require => false
15
- gem "memory_profiler", :require => false
16
- gem "codeclimate-test-reporter", :require => false
19
+ gem "travis", :require => false
17
20
  end
18
21
 
19
22
  gemspec :path => "../"
@@ -1,4 +1,4 @@
1
- require 'yaml' if RUBY_VERSION.include?('2.0.0') # rubocop:disable FileName
1
+ require 'yaml' if RUBY_VERSION.include?('2.0.0')
2
2
  require 'forwardable'
3
3
  require 'sidekiq_unique_jobs/version'
4
4
  require 'sidekiq_unique_jobs/constants'
@@ -1,19 +1,11 @@
1
1
  module SidekiqUniqueJobs
2
2
  class Config < OpenStruct
3
- CONFIG_ACCESSORS = [
4
- :unique_prefix,
5
- :default_queue_lock_expiration,
6
- :default_run_lock_expiration,
7
- :default_lock,
8
- :redis_mode
9
- ].freeze
10
-
11
3
  def inline_testing_enabled?
12
4
  testing_enabled? && Sidekiq::Testing.inline?
13
5
  end
14
6
 
15
7
  def mocking?
16
- inline_testing_enabled? && redis_test_mode.to_sym == :mock
8
+ redis_test_mode.to_sym == :mock
17
9
  end
18
10
 
19
11
  def testing_enabled?
@@ -5,6 +5,7 @@ module SidekiqUniqueJobs
5
5
  JID_KEY ||= 'jid'.freeze
6
6
  LOG_DUPLICATE_KEY ||= 'log_duplicate_payload'.freeze
7
7
  QUEUE_KEY ||= 'queue'.freeze
8
+ HASH_KEY ||= 'uniquejobs'.freeze
8
9
  QUEUE_LOCK_TIMEOUT_KEY ||= 'unique_expiration'.freeze
9
10
  RUN_LOCK_TIMEOUT_KEY ||= 'run_lock_expiration'.freeze
10
11
  TESTING_CONSTANT ||= 'Testing'.freeze
@@ -3,49 +3,59 @@ begin
3
3
  require 'active_support/core_ext/hash/deep_merge'
4
4
  rescue LoadError
5
5
  class Hash
6
- def slice(*keys)
7
- keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
8
- keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if key?(k) }
9
- end unless {}.respond_to?(:slice)
6
+ unless {}.respond_to?(:slice)
7
+ def slice(*keys)
8
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
9
+ keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if key?(k) }
10
+ end
11
+ end
10
12
 
11
- def slice!(*keys)
12
- keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
13
- omit = slice(*self.keys - keys)
14
- hash = slice(*keys)
15
- hash.default = default
16
- hash.default_proc = default_proc if default_proc
17
- replace(hash)
18
- omit
19
- end unless {}.respond_to?(:slice!)
13
+ unless {}.respond_to?(:slice!)
14
+ def slice!(*keys)
15
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
16
+ omit = slice(*self.keys - keys)
17
+ hash = slice(*keys)
18
+ hash.default = default
19
+ hash.default_proc = default_proc if default_proc
20
+ replace(hash)
21
+ omit
22
+ end
23
+ end
20
24
  end
21
25
  end
22
26
 
23
27
  class Array
24
- def extract_options!
25
- if last.is_a?(Hash) && last.instance_of?(Hash)
26
- pop
27
- else
28
- {}
28
+ unless [].respond_to?(:extract_options!)
29
+ def extract_options!
30
+ if last.is_a?(Hash) && last.instance_of?(Hash)
31
+ pop
32
+ else
33
+ {}
34
+ end
29
35
  end
30
- end unless [].respond_to?(:extract_options!)
36
+ end
31
37
  end
32
38
 
33
39
  class String
34
- def classify
35
- camelize(sub(/.*\./, ''))
36
- end unless ''.respond_to?(:classify)
40
+ unless ''.respond_to?(:classify)
41
+ def classify
42
+ camelize(sub(/.*\./, ''))
43
+ end
44
+ end
37
45
 
38
- def camelize(uppercase_first_letter = true)
39
- string = self
40
- string = if uppercase_first_letter
41
- string.sub(/^[a-z\d]*/) { $&.capitalize }
42
- else
43
- string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { $&.downcase }
44
- end
45
- string.gsub!(%r{(?:_|(\/))([a-z\d]*)}i) do
46
- "#{Regexp.last_match(1)}#{Regexp.last_match(2).capitalize}"
46
+ unless ''.respond_to?(:camelize)
47
+ def camelize(uppercase_first_letter = true)
48
+ string = self
49
+ string = if uppercase_first_letter
50
+ string.sub(/^[a-z\d]*/) { $&.capitalize }
51
+ else
52
+ string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { $&.downcase }
53
+ end
54
+ string.gsub!(%r{(?:_|(\/))([a-z\d]*)}i) do
55
+ "#{Regexp.last_match(1)}#{Regexp.last_match(2).capitalize}"
56
+ end
57
+ string.gsub!(%r{/}, '::')
58
+ string
47
59
  end
48
- string.gsub!(%r{/}, '::')
49
- string
50
- end unless ''.respond_to?(:camelize)
60
+ end
51
61
  end
@@ -14,7 +14,7 @@ module SidekiqUniqueJobs
14
14
 
15
15
  def synchronize
16
16
  @mutex.lock
17
- sleep 0.001 until locked?
17
+ sleep 0.1 until locked?
18
18
 
19
19
  yield
20
20
  rescue Sidekiq::Shutdown
@@ -21,12 +21,9 @@ module SidekiqUniqueJobs
21
21
 
22
22
  return stored_jid == job_id ? 1 : 0 if stored_jid
23
23
 
24
- if redis.set(unique_key, job_id, nx: true, ex: expires)
25
- redis.hsetnx('uniquejobs', job_id, unique_key)
26
- return 1
27
- else
28
- return 0
29
- end
24
+ return 0 unless redis.set(unique_key, job_id, nx: true, ex: expires)
25
+ redis.hsetnx(SidekiqUniqueJobs::HASH_KEY, job_id, unique_key)
26
+ return 1
30
27
  end
31
28
  end
32
29
 
@@ -40,6 +37,7 @@ module SidekiqUniqueJobs
40
37
  return 0 unless stored_jid == job_id || stored_jid == '2'
41
38
 
42
39
  redis.del(unique_key)
40
+ redis.hdel(SidekiqUniqueJobs::HASH_KEY, job_id)
43
41
  return 1
44
42
  end
45
43
  end
@@ -50,7 +48,6 @@ module SidekiqUniqueJobs
50
48
  time = options[:argv][0].to_i
51
49
  expires = options[:argv][1].to_f
52
50
 
53
- stored_jid = redis.get(unique_key).to_i
54
51
  return 1 if redis.set(unique_key, time + expires, nx: true, ex: expires)
55
52
 
56
53
  stored_time = redis.get(unique_key)