activejob-uniqueness 0.1.2 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff1cfb19bc51b7eb8f4040f700650c51a47376e1ec96c84ae72b764227911f0c
4
- data.tar.gz: 3813cf68d80e7d56d828e15f179c677e49fe2f171780e25c0a6990b7b93eed76
3
+ metadata.gz: 56ef0f3d36e4bbad62cd210b5e0d57798854e01b3ca539bcdcec73901d6b3565
4
+ data.tar.gz: 1c76f1e1d906d7caacc3948cb55aa6ac89842ff8ef00e2f54f2200fbc3869475
5
5
  SHA512:
6
- metadata.gz: b616c4460d8bffe1be31226c3d18d9d3a7197fd714d680ddd636b154934ff648fb5dface28b0099b59ac865a91a5a0cec85a8230ba8d442bda6f831535405b94
7
- data.tar.gz: 938eb49268486827b8b946934838af755f7f449fc75e84f2cde8538e49af7e786edc13583a715ad86b2203a58867e324e8e580cc611d522e512ae7ed235ddae1
6
+ metadata.gz: 20c7aa349360a2f0dae02ac661b572f8c7b524071407e315d868998cd616f36631c42cce6cecbae4f2668cda1e0543e1e5c7f9b4e0f27a9a23bfa5c4a72aa637
7
+ data.tar.gz: 58dee76d6d5ef595920dbee7fdea277f8597ff4e12a11ad2373e5667eea4bb7cb33363ebfbfe5445a693ec875745bf46187668c4b20a5e96dc6c988b4c4b1b1b
data/CHANGELOG.md CHANGED
@@ -1,14 +1,53 @@
1
- ## Changes Between 0.1.1 and 0.1.2
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
2
3
 
3
- Release lock for Sidekiq adapter when all Sidekiq attempts were unsuccessful or job is deleted manually from Sidekiq::Web
4
- [PR](https://github.com/veeqo/activejob-uniqueness/pull/5) by @vbyno
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
 
6
- ## Changes Between 0.1.0 and 0.1.1
6
+ ## [Unreleased](https://github.com/veeqo/activejob-uniqueness/compare/v0.2.0...HEAD)
7
7
 
8
- Fixed NoMethodError on `Rails.application.eager_load!` in Rails initializer
9
- ```
10
- NoMethodError: undefined method `unique' for MyJob:Class
11
- ```
12
- [PR](https://github.com/veeqo/activejob-uniqueness/pull/4)
8
+ ## [0.2.1](https://github.com/veeqo/activejob-uniqueness/compare/v0.2.0...v0.2.1) - 2021-08-24
13
9
 
14
- ## Original Release: 0.1.0
10
+ ### Added
11
+ - [#30](https://github.com/veeqo/activejob-uniqueness/pull/30) Add Sidekiq::JobRecord support (reported by [@dwightwatson](https://github.com/dwightwatson))
12
+
13
+ ## [0.2.0](https://github.com/veeqo/activejob-uniqueness/compare/v0.1.4...v0.2.0) - 2021-05-09
14
+
15
+ ### Added
16
+ - [#22](https://github.com/veeqo/activejob-uniqueness/pull/22) Test with ruby 3.0.1
17
+
18
+ ### Changed
19
+ - [#20](https://github.com/veeqo/activejob-uniqueness/pull/20) **Breaking** Sidekiq patch is not applied automatically anymore
20
+ - [#21](https://github.com/veeqo/activejob-uniqueness/pull/21) Migrate from Travis to Github Actions
21
+ - [#24](https://github.com/veeqo/activejob-uniqueness/pull/24) The default value for `retry_count` of redlock is now 0
22
+ - Require ruby 2.5+
23
+
24
+ ## [0.1.4](https://github.com/veeqo/activejob-uniqueness/compare/v0.1.3...v0.1.4) - 2020-09-22
25
+
26
+ ### Fixed
27
+ - [#11](https://github.com/veeqo/activejob-uniqueness/pull/11) Fix deprecation warnings for ruby 2.7 by [@DanAndreasson](https://github.com/DanAndreasson)
28
+ - [#13](https://github.com/veeqo/activejob-uniqueness/pull/13) Fix deprecation warnings for ruby 2.7
29
+
30
+ ## [0.1.3](https://github.com/veeqo/activejob-uniqueness/compare/v0.1.2...v0.1.3) - 2020-08-17
31
+
32
+ ### Fixed
33
+ - [#7](https://github.com/veeqo/activejob-uniqueness/pull/7) Fix deprecation warnings for ruby 2.7 by [@tonobo](https://github.com/tonobo)
34
+
35
+ ### Changed
36
+ - [#8](https://github.com/veeqo/activejob-uniqueness/pull/8) Use appraisal gem to control gem versions of tests matrix
37
+ - [#9](https://github.com/veeqo/activejob-uniqueness/pull/9) Refactor of Sidekiq API patch. Fixes [#6](https://github.com/veeqo/activejob-uniqueness/issues/6) Rails boot error for version 0.1.2
38
+ - [#10](https://github.com/veeqo/activejob-uniqueness/pull/10) Refactor changelog to comply with Keep a Changelog
39
+
40
+ ## [0.1.2](https://github.com/veeqo/activejob-uniqueness/compare/v0.1.1...v0.1.2) - 2020-07-30
41
+
42
+ ### Added
43
+ - [#5](https://github.com/veeqo/activejob-uniqueness/pull/5) Release lock for Sidekiq adapter by [@vbyno](https://github.com/vbyno)
44
+
45
+ ## [0.1.1](https://github.com/veeqo/activejob-uniqueness/compare/v0.1.0...v0.1.1) - 2020-07-23
46
+
47
+ ### Fixed
48
+ - [#4](https://github.com/veeqo/activejob-uniqueness/pull/4) Fix `NoMethodError` on `Rails.application.eager_load!` in Rails initializer
49
+
50
+ ## [0.1.0](https://github.com/veeqo/activejob-uniqueness/releases/tag/v0.1.0) - 2020-07-05
51
+
52
+ ### Added
53
+ - Job uniqueness for ActiveJob
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Job uniqueness for ActiveJob
2
- [![Build Status](https://travis-ci.com/veeqo/activejob-uniqueness.svg?branch=master)](https://travis-ci.com/veeqo/activejob-uniqueness) [![Gem Version](https://badge.fury.io/rb/activejob-uniqueness.svg)](https://badge.fury.io/rb/activejob-uniqueness)
2
+ [![Build Status](https://github.com/veeqo/activejob-uniqueness/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/veeqo/activejob-uniqueness/actions/workflows/main.yml) [![Gem Version](https://badge.fury.io/rb/activejob-uniqueness.svg)](https://badge.fury.io/rb/activejob-uniqueness)
3
3
 
4
4
  The gem allows to protect job uniqueness with next strategies:
5
5
 
@@ -8,10 +8,16 @@ The gem allows to protect job uniqueness with next strategies:
8
8
  | `until_executing` | when **pushed** to the queue | when **processing starts** |
9
9
  | `until_executed` | when **pushed** to the queue | when the job is **processed successfully** |
10
10
  | `until_expired` | when **pushed** to the queue | when the lock is **expired** |
11
- | `until_and_while_executing` | when **pushed** to the queue | when **processing starts**<br>a runtime lock is acquired to **prevent simultaneous jobs** |
11
+ | `until_and_while_executing` | when **pushed** to the queue | when **processing starts**<br>a runtime lock is acquired to **prevent simultaneous jobs**<br>*has extra options: `runtime_lock_ttl`, `on_runtime_conflict`* |
12
12
  | `while_executing` | when **processing starts** | when the job is **processed**<br>with any result including an error |
13
13
 
14
- Inspired by [SidekiqUniqueJobs](https://github.com/mhenrixon/sidekiq-unique-jobs), uses [Redlock](https://github.com/leandromoreira/redlock-rb) under the hood, sponsored by [Veeqo](https://www.veeqo.com/).
14
+ Inspired by [SidekiqUniqueJobs](https://github.com/mhenrixon/sidekiq-unique-jobs), uses [Redlock](https://github.com/leandromoreira/redlock-rb) under the hood.
15
+
16
+ <p align="center">
17
+ <a href="https://www.veeqo.com/" title="Sponsored by Veeqo">
18
+ <img src="https://static.veeqo.com/assets/sponsored_by_veeqo.png" width="360" />
19
+ </a>
20
+ </p>
15
21
 
16
22
  ## Installation
17
23
 
@@ -21,6 +27,11 @@ Add the `activejob-uniqueness` gem to your Gemfile.
21
27
  gem 'activejob-uniqueness'
22
28
  ```
23
29
 
30
+ If you want jobs unlocking for Sidekiq Web UI, require the patch explicitly. [**Queues cleanup becomes slower!**](#sidekiq-api-support)
31
+ ```ruby
32
+ gem 'activejob-uniqueness', require: 'active_job/uniqueness/sidekiq_patch'
33
+ ```
34
+
24
35
  And run `bundle install` command.
25
36
 
26
37
  ## Configuration
@@ -34,27 +45,83 @@ rails generate active_job:uniqueness:install
34
45
 
35
46
  ## Usage
36
47
 
37
- Define uniqueness strategy for your job via `unique` class method:
48
+
49
+ ### Make the job to be unique
50
+
51
+ ```ruby
52
+ class MyJob < ActiveJob::Base
53
+ # new jobs with the same args will raise error until existing one is executed
54
+ unique :until_executed
55
+
56
+ def perform(args)
57
+ # work
58
+ end
59
+ end
60
+ ```
61
+
62
+ ### Tune uniqueness settings per job
63
+
64
+ ```ruby
65
+ class MyJob < ActiveJob::Base
66
+ # new jobs with the same args will be logged within 3 hours or until existing one is being executing
67
+ unique :until_executing, lock_ttl: 3.hours, on_conflict: :log
68
+
69
+ def perform(args)
70
+ # work
71
+ end
72
+ end
73
+ ```
74
+
75
+ You can set defaults globally with [the configuration](#configuration)
76
+
77
+ ### Control lock conflicts
78
+
79
+ ```ruby
80
+ class MyJob < ActiveJob::Base
81
+ # Proc gets the job instance including its arguments
82
+ unique :until_executing, on_conflict: ->(job) { job.logger.info "Oops: #{job.arguments}" }
83
+
84
+ def perform(args)
85
+ # work
86
+ end
87
+ end
88
+ ```
89
+
90
+ ### Control lock key arguments
38
91
 
39
92
  ```ruby
40
93
  class MyJob < ActiveJob::Base
41
94
  unique :until_executed
42
95
 
43
- # Custom expiration:
44
- # unique :until_executed, lock_ttl: 3.hours
96
+ def perform(foo, bar, baz)
97
+ # work
98
+ end
45
99
 
46
- # Do not raise error on non unique jobs enqueuing:
47
- # unique :until_executed, on_conflict: :log
100
+ def lock_key_arguments
101
+ arguments.first(2) # baz is ignored
102
+ end
103
+ end
104
+ ```
48
105
 
49
- # Handle conflict by custom Proc:
50
- # unique :until_executed, on_conflict: ->(job) { job.logger.info 'Oops' }
106
+ ### Control the lock key
51
107
 
52
- # The :until_and_while_executing strategy supports extra attributes for a runtime lock:
53
- # unique :until_and_while_executing runtime_lock_ttl: 10.minutes, on_runtime_conflict: :log
108
+ ```ruby
109
+ class MyJob < ActiveJob::Base
110
+ unique :until_executed
111
+
112
+ def perform(foo, bar, baz)
113
+ # work
114
+ end
115
+
116
+ def lock_key
117
+ 'qux' # completely custom lock key
118
+ end
54
119
  end
55
120
  ```
56
121
 
57
- ActiveJob::Uniqueness allows to manually unlock jobs:
122
+ ### Unlock jobs manually
123
+
124
+ The selected strategy automatically unlocks jobs, but in some cases (e.g. the queue is purged) it is handy to unlock jobs manually.
58
125
 
59
126
  ```ruby
60
127
  # Remove the lock for particular arguments:
@@ -91,7 +158,30 @@ ActiveJob::Uniqueness instruments `ActiveSupport::Notifications` with next event
91
158
 
92
159
  And then writes to `ActiveJob::Base.logger`.
93
160
 
94
- ### ActiveJob prior to version `6.1` will always log `Enqueued MyJob (Job ID) ...` even if the callback chain was halted. [Details](https://github.com/rails/rails/pull/37830)
161
+ **ActiveJob prior to version `6.1` will always log `Enqueued MyJob (Job ID) ...` even if the callback chain is halted. [Details](https://github.com/rails/rails/pull/37830)**
162
+
163
+ ## Testing
164
+
165
+ Run redis server (in separate console):
166
+ ```
167
+ docker run --rm -p 6379:6379 redis
168
+ ```
169
+
170
+ Run tests with:
171
+
172
+ ```sh
173
+ bundle
174
+ rake
175
+ ```
176
+
177
+ ## Sidekiq API support
178
+
179
+ ActiveJob::Uniqueness supports Sidekiq API to unset job locks on queues cleanup (e.g. via Sidekiq Web UI). Starting Sidekiq 5.1 job death also triggers locks cleanup.
180
+ Take into account that **[big queues clanup becomes much slower](https://github.com/veeqo/activejob-uniqueness/issues/16)** because each job is being unlocked individually. In order to activate Sidekiq API patch require it explicitly in your Gemfile:
181
+
182
+ ```ruby
183
+ gem 'activejob-uniqueness', require: 'active_job/uniqueness/sidekiq_patch'
184
+ ```
95
185
 
96
186
  ## Contributing
97
187
 
@@ -100,3 +190,9 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/veeqo/
100
190
  ## License
101
191
 
102
192
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
193
+
194
+ ## About [Veeqo](https://www.veeqo.com)
195
+
196
+ At Veeqo, our team of Engineers is on a mission to create a world-class Inventory and Shipping platform, built to the highest standards in best coding practices. We are a growing team, looking for other passionate developers to [join us](https://veeqo-ltd.breezy.hr/) on our journey. If you're looking for a career working for one of the most exciting tech companies in ecommerce, we want to hear from you.
197
+
198
+ [Veeqo developers blog](https://devs.veeqo.com)
@@ -16,7 +16,7 @@ module ActiveJob
16
16
  # end
17
17
  # end
18
18
  #
19
- module Patch
19
+ module ActiveJobPatch
20
20
  extend ActiveSupport::Concern
21
21
 
22
22
  class_methods do
@@ -55,7 +55,7 @@ module ActiveJob
55
55
  end
56
56
 
57
57
  def lock_strategy
58
- @lock_strategy ||= lock_strategy_class.new(lock_options.merge(lock_key: lock_key, job: self))
58
+ @lock_strategy ||= lock_strategy_class.new(**lock_options.merge(lock_key: lock_key, job: self))
59
59
  end
60
60
 
61
61
  # Override in your job class if you want to customize arguments set for a digest.
@@ -73,12 +73,7 @@ module ActiveJob
73
73
  end
74
74
 
75
75
  ActiveSupport.on_load(:active_job) do
76
- ActiveJob::Base.include ActiveJob::Uniqueness::Patch
77
-
78
- if ::ActiveJob.const_defined?(:Railtie) &&
79
- ActiveJob::Railtie.config.active_job.queue_adapter.to_sym == :sidekiq
80
- require_relative 'patch/sidekiq'
81
- end
76
+ ActiveJob::Base.include ActiveJob::Uniqueness::ActiveJobPatch
82
77
  end
83
78
  end
84
79
  end
@@ -11,14 +11,18 @@ module ActiveJob
11
11
  class Configuration
12
12
  include ActiveSupport::Configurable
13
13
 
14
- config_accessor(:lock_ttl) { 1.day }
14
+ config_accessor(:lock_ttl) { 86_400 } # 1.day
15
15
  config_accessor(:lock_prefix) { 'activejob_uniqueness' }
16
16
  config_accessor(:on_conflict) { :raise }
17
- config_accessor(:digest_method) { OpenSSL::Digest::MD5 }
18
17
  config_accessor(:redlock_servers) { [ENV.fetch('REDIS_URL', 'redis://localhost:6379')] }
19
- config_accessor(:redlock_options) { {} }
18
+ config_accessor(:redlock_options) { { retry_count: 0 } }
20
19
  config_accessor(:lock_strategies) { {} }
21
20
 
21
+ config_accessor(:digest_method) do
22
+ require 'openssl'
23
+ OpenSSL::Digest::MD5
24
+ end
25
+
22
26
  def on_conflict=(action)
23
27
  validate_on_conflict_action!(action)
24
28
 
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'activejob/uniqueness'
4
+ require 'sidekiq/api'
5
+
6
+ module ActiveJob
7
+ module Uniqueness
8
+ def self.unlock_sidekiq_job!(job_data)
9
+ return unless job_data['class'] == 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper' # non ActiveJob jobs
10
+
11
+ job = ActiveJob::Base.deserialize(job_data.fetch('args').first)
12
+
13
+ return unless job.class.lock_strategy_class
14
+
15
+ begin
16
+ job.send(:deserialize_arguments_if_needed)
17
+ rescue ActiveJob::DeserializationError
18
+ # Most probably, GlobalID fails to locate AR record (record is deleted)
19
+ else
20
+ ActiveJob::Uniqueness.unlock!(job_class_name: job.class.name, arguments: job.arguments)
21
+ end
22
+ end
23
+
24
+ module SidekiqPatch
25
+ module SortedEntry
26
+ def delete
27
+ ActiveJob::Uniqueness.unlock_sidekiq_job!(item) if super
28
+ item
29
+ end
30
+
31
+ private
32
+
33
+ def remove_job
34
+ super do |message|
35
+ ActiveJob::Uniqueness.unlock_sidekiq_job!(Sidekiq.load_json(message))
36
+ yield message
37
+ end
38
+ end
39
+ end
40
+
41
+ module ScheduledSet
42
+ def delete(score, job_id)
43
+ entry = find_job(job_id)
44
+ ActiveJob::Uniqueness.unlock_sidekiq_job!(entry.item) if super(score, job_id)
45
+ entry
46
+ end
47
+ end
48
+
49
+ module Job
50
+ def delete
51
+ ActiveJob::Uniqueness.unlock_sidekiq_job!(item)
52
+ super
53
+ end
54
+ end
55
+
56
+ module Queue
57
+ def clear
58
+ each(&:delete)
59
+ super
60
+ end
61
+ end
62
+
63
+ module JobSet
64
+ def clear
65
+ each(&:delete)
66
+ super
67
+ end
68
+
69
+ def delete_by_value(name, value)
70
+ ActiveJob::Uniqueness.unlock_sidekiq_job!(Sidekiq.load_json(value)) if super(name, value)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ Sidekiq::SortedEntry.prepend ActiveJob::Uniqueness::SidekiqPatch::SortedEntry
78
+ Sidekiq::ScheduledSet.prepend ActiveJob::Uniqueness::SidekiqPatch::ScheduledSet
79
+ Sidekiq::Queue.prepend ActiveJob::Uniqueness::SidekiqPatch::Queue
80
+ Sidekiq::JobSet.prepend ActiveJob::Uniqueness::SidekiqPatch::JobSet
81
+
82
+ sidekiq_version = Gem::Version.new(Sidekiq::VERSION)
83
+
84
+ # Sidekiq 6.2.2 renames Sidekiq::Job to Sidekiq::JobRecord
85
+ # https://github.com/mperham/sidekiq/issues/4955
86
+ if sidekiq_version >= Gem::Version.new('6.2.2')
87
+ Sidekiq::JobRecord.prepend ActiveJob::Uniqueness::SidekiqPatch::Job
88
+ else
89
+ Sidekiq::Job.prepend ActiveJob::Uniqueness::SidekiqPatch::Job
90
+ end
91
+
92
+ # Global death handlers are introduced in Sidekiq 5.1
93
+ # https://github.com/mperham/sidekiq/blob/e7acb124fbeb0bece0a7c3d657c39a9cc18d72c6/Changes.md#510
94
+ if sidekiq_version >= Gem::Version.new('5.1')
95
+ Sidekiq.death_handlers << ->(job, _ex) { ActiveJob::Uniqueness.unlock_sidekiq_job!(job) }
96
+ end
@@ -12,7 +12,7 @@ module ActiveJob
12
12
  attr_reader :runtime_lock_ttl, :on_runtime_conflict
13
13
 
14
14
  def initialize(runtime_lock_ttl: nil, on_runtime_conflict: nil, **params)
15
- super(params)
15
+ super(**params)
16
16
  @runtime_lock_ttl = runtime_lock_ttl.present? ? runtime_lock_ttl.to_i * 1000 : lock_ttl
17
17
  @on_runtime_conflict = on_runtime_conflict || on_conflict
18
18
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveJob
4
4
  module Uniqueness
5
- VERSION = '0.1.2'
5
+ VERSION = '0.2.1'
6
6
  end
7
7
  end
@@ -1,13 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support'
4
- require 'active_support/core_ext'
3
+ require 'active_job'
5
4
  require 'redlock'
6
- require 'openssl'
5
+
7
6
  require 'active_job/uniqueness/version'
8
7
  require 'active_job/uniqueness/errors'
9
8
  require 'active_job/uniqueness/log_subscriber'
10
- require 'active_job/uniqueness/patch'
9
+ require 'active_job/uniqueness/active_job_patch'
11
10
 
12
11
  module ActiveJob
13
12
  module Uniqueness
@@ -32,8 +31,8 @@ module ActiveJob
32
31
  @lock_manager ||= ActiveJob::Uniqueness::LockManager.new(config.redlock_servers, config.redlock_options)
33
32
  end
34
33
 
35
- def unlock!(*args)
36
- lock_manager.delete_locks(ActiveJob::Uniqueness::LockKey.new(*args).wildcard_key)
34
+ def unlock!(**args)
35
+ lock_manager.delete_locks(ActiveJob::Uniqueness::LockKey.new(**args).wildcard_key)
37
36
  end
38
37
 
39
38
  def test_mode!
@@ -31,7 +31,7 @@ ActiveJob::Uniqueness.configure do |config|
31
31
  # Custom options for Redlock.
32
32
  # Read more at https://github.com/leandromoreira/redlock-rb#redlock-configuration
33
33
  #
34
- # config.redlock_options = {}
34
+ # config.redlock_options = { retry_count: 0 }
35
35
 
36
36
  # Custom strategies.
37
37
  # config.lock_strategies = { my_strategy: MyStrategy }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activejob-uniqueness
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rustam Sharshenov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-30 00:00:00.000000000 Z
11
+ date: 2021-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -17,6 +17,9 @@ dependencies:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '4.2'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '7'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +27,9 @@ dependencies:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: '4.2'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '7'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: redlock
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -45,35 +51,35 @@ dependencies:
45
51
  - !ruby/object:Gem::Version
46
52
  version: '2'
47
53
  - !ruby/object:Gem::Dependency
48
- name: bundler
54
+ name: appraisal
49
55
  requirement: !ruby/object:Gem::Requirement
50
56
  requirements:
51
- - - ">="
57
+ - - "~>"
52
58
  - !ruby/object:Gem::Version
53
- version: '0'
59
+ version: 2.3.0
54
60
  type: :development
55
61
  prerelease: false
56
62
  version_requirements: !ruby/object:Gem::Requirement
57
63
  requirements:
58
- - - ">="
64
+ - - "~>"
59
65
  - !ruby/object:Gem::Version
60
- version: '0'
66
+ version: 2.3.0
61
67
  - !ruby/object:Gem::Dependency
62
- name: pry-byebug
68
+ name: bundler
63
69
  requirement: !ruby/object:Gem::Requirement
64
70
  requirements:
65
71
  - - ">="
66
72
  - !ruby/object:Gem::Version
67
- version: '0'
73
+ version: '2.0'
68
74
  type: :development
69
75
  prerelease: false
70
76
  version_requirements: !ruby/object:Gem::Requirement
71
77
  requirements:
72
78
  - - ">="
73
79
  - !ruby/object:Gem::Version
74
- version: '0'
80
+ version: '2.0'
75
81
  - !ruby/object:Gem::Dependency
76
- name: rake
82
+ name: pry-byebug
77
83
  requirement: !ruby/object:Gem::Requirement
78
84
  requirements:
79
85
  - - ">="
@@ -107,24 +113,17 @@ executables: []
107
113
  extensions: []
108
114
  extra_rdoc_files: []
109
115
  files:
110
- - ".gitignore"
111
- - ".rspec"
112
- - ".rubocop.yml"
113
- - ".travis.yml"
114
116
  - CHANGELOG.md
115
- - Gemfile
116
117
  - LICENSE.txt
117
118
  - README.md
118
- - Rakefile
119
- - activejob-uniqueness.gemspec
120
119
  - lib/active_job/uniqueness.rb
120
+ - lib/active_job/uniqueness/active_job_patch.rb
121
121
  - lib/active_job/uniqueness/configuration.rb
122
122
  - lib/active_job/uniqueness/errors.rb
123
123
  - lib/active_job/uniqueness/lock_key.rb
124
124
  - lib/active_job/uniqueness/lock_manager.rb
125
125
  - lib/active_job/uniqueness/log_subscriber.rb
126
- - lib/active_job/uniqueness/patch.rb
127
- - lib/active_job/uniqueness/patch/sidekiq.rb
126
+ - lib/active_job/uniqueness/sidekiq_patch.rb
128
127
  - lib/active_job/uniqueness/strategies.rb
129
128
  - lib/active_job/uniqueness/strategies/base.rb
130
129
  - lib/active_job/uniqueness/strategies/until_and_while_executing.rb
@@ -143,7 +142,7 @@ licenses:
143
142
  metadata:
144
143
  homepage_uri: https://github.com/veeqo/activejob-uniqueness
145
144
  source_code_uri: https://github.com/veeqo/activejob-uniqueness
146
- changelog_uri: https://github.com/veeqo/activejob-uniqueness/blob/master/CHANGELOG.md
145
+ changelog_uri: https://github.com/veeqo/activejob-uniqueness/blob/main/CHANGELOG.md
147
146
  post_install_message:
148
147
  rdoc_options: []
149
148
  require_paths:
@@ -152,14 +151,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
152
151
  requirements:
153
152
  - - ">="
154
153
  - !ruby/object:Gem::Version
155
- version: '0'
154
+ version: '2.5'
156
155
  required_rubygems_version: !ruby/object:Gem::Requirement
157
156
  requirements:
158
157
  - - ">="
159
158
  - !ruby/object:Gem::Version
160
159
  version: '0'
161
160
  requirements: []
162
- rubygems_version: 3.0.6
161
+ rubygems_version: 3.0.9
163
162
  signing_key:
164
163
  specification_version: 4
165
164
  summary: Ensure uniqueness of your ActiveJob jobs
data/.gitignore DELETED
@@ -1,14 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- /Gemfile.lock
10
- /.ruby-gemset
11
- /.ruby-version
12
-
13
- # rspec failure tracking
14
- .rspec_status
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,38 +0,0 @@
1
- AllCops:
2
- NewCops: enable
3
-
4
- Layout/LineLength:
5
- Max: 120
6
- Exclude:
7
- - spec/**/*
8
-
9
- Layout/MultilineMethodCallIndentation:
10
- Exclude:
11
- - spec/**/*
12
-
13
- Lint/AmbiguousBlockAssociation:
14
- Exclude:
15
- - spec/**/*
16
-
17
- Metrics/AbcSize:
18
- Exclude:
19
- - spec/**/*
20
-
21
- Metrics/BlockLength:
22
- Exclude:
23
- - activejob-uniqueness.gemspec
24
- - spec/**/*
25
-
26
- Metrics/MethodLength:
27
- Exclude:
28
- - spec/**/*
29
-
30
- Style/ClassAndModuleChildren:
31
- Exclude:
32
- - spec/**/*
33
-
34
- Style/Documentation:
35
- Enabled: false
36
-
37
- Style/RescueModifier:
38
- Enabled: false
data/.travis.yml DELETED
@@ -1,22 +0,0 @@
1
- ---
2
- dist: xenial
3
- language: ruby
4
- services:
5
- - redis-server
6
- cache: bundler
7
- rvm:
8
- - 2.5.8
9
- - 2.6.6
10
- - 2.7.1
11
- env:
12
- - ACTIVEJOB_VERSION="~> 4.2.11"
13
- - ACTIVEJOB_VERSION="~> 5.2.4"
14
- - ACTIVEJOB_VERSION="~> 6.0.3"
15
- - ACTIVEJOB_VERSION="~> 6.0.3" SIDEKIQ_VERSION="~> 6.0.0"
16
- jobs:
17
- exclude:
18
- - rvm: 2.7.1
19
- env: ACTIVEJOB_VERSION="~> 4.2.11"
20
-
21
- before_install: gem install bundler -v 1.17.3
22
- bundler_args: --jobs 3 --retry 3
data/Gemfile DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
-
7
- # Specify your gem's dependencies in activejob-uniqueness.gemspec
8
- gemspec
9
-
10
- gem 'activejob', ENV.fetch('ACTIVEJOB_VERSION', '~> 4.2.11')
11
-
12
- if ENV['SIDEKIQ_VERSION']
13
- gem 'sidekiq', ENV.fetch('SIDEKIQ_VERSION')
14
- gem 'railties', ENV.fetch('ACTIVEJOB_VERSION')
15
- end
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task default: :spec
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- lib = File.expand_path('lib', __dir__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'active_job/uniqueness/version'
6
-
7
- Gem::Specification.new do |spec|
8
- spec.name = 'activejob-uniqueness'
9
- spec.version = ActiveJob::Uniqueness::VERSION
10
- spec.authors = ['Rustam Sharshenov']
11
- spec.email = ['rustam@sharshenov.com']
12
-
13
- spec.summary = 'Ensure uniqueness of your ActiveJob jobs'
14
- spec.description = 'Ensure uniqueness of your ActiveJob jobs'
15
- spec.homepage = 'https://github.com/veeqo/activejob-uniqueness'
16
- spec.license = 'MIT'
17
-
18
- if spec.respond_to?(:metadata)
19
- spec.metadata['homepage_uri'] = spec.homepage
20
- spec.metadata['source_code_uri'] = spec.homepage
21
- spec.metadata['changelog_uri'] = 'https://github.com/veeqo/activejob-uniqueness/blob/master/CHANGELOG.md'
22
- end
23
-
24
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|\.rubocop.yml)/}) }
26
- end
27
- spec.require_paths = ['lib']
28
-
29
- spec.add_dependency 'activejob', '>= 4.2'
30
- spec.add_dependency 'redlock', '>= 1.2', '< 2'
31
-
32
- spec.add_development_dependency 'bundler'
33
- spec.add_development_dependency 'pry-byebug'
34
- spec.add_development_dependency 'rake'
35
- spec.add_development_dependency 'rspec', '~> 3.0'
36
- end
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveJob
4
- module Uniqueness
5
- module Patch
6
- def self.delete_sidekiq_job!(job)
7
- ActiveJob::Uniqueness.unlock!(
8
- job_class_name: job.fetch('wrapped'),
9
- arguments: job.fetch('args').first.fetch('arguments')
10
- )
11
- end
12
- end
13
- end
14
- end
15
-
16
- require 'sidekiq/api'
17
-
18
- Sidekiq.configure_server do |config|
19
- config.death_handlers << ->(job, _ex) do
20
- ActiveJob::Uniqueness::Patch.delete_sidekiq_job!(job)
21
- end
22
- end
23
-
24
- module Sidekiq
25
- class SortedEntry
26
- module UniqueExtension
27
- def delete
28
- ActiveJob::Uniqueness::Patch.delete_sidekiq_job!(item) if super
29
- item
30
- end
31
-
32
- private
33
-
34
- def remove_job
35
- super do |message|
36
- ActiveJob::Uniqueness::Patch.delete_sidekiq_job!(Sidekiq.load_json(message))
37
- yield message
38
- end
39
- end
40
- end
41
-
42
- prepend UniqueExtension
43
- end
44
-
45
- class ScheduledSet
46
- module UniqueExtension
47
- def delete(score, job_id)
48
- entry = find_job(job_id)
49
- ActiveJob::Uniqueness::Patch.delete_sidekiq_job!(entry.item) if super(score, job_id)
50
- entry
51
- end
52
- end
53
-
54
- prepend UniqueExtension
55
- end
56
-
57
- class Job
58
- module UniqueExtension
59
- def delete
60
- ActiveJob::Uniqueness::Patch.delete_sidekiq_job!(item)
61
- super
62
- end
63
- end
64
-
65
- prepend UniqueExtension
66
- end
67
-
68
- class Queue
69
- module UniqueExtension
70
- def clear
71
- each(&:delete)
72
- super
73
- end
74
- end
75
-
76
- prepend UniqueExtension
77
- end
78
-
79
- class JobSet
80
- module UniqueExtension
81
- def clear
82
- each(&:delete)
83
- super
84
- end
85
-
86
- def delete_by_value(name, value)
87
- ActiveJob::Uniqueness::Patch.delete_sidekiq_job!(Sidekiq.load_json(value)) if super(name, value)
88
- end
89
- end
90
-
91
- prepend UniqueExtension
92
- end
93
- end