activejob-uniqueness 0.1.2 → 0.4.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +115 -10
- data/README.md +140 -14
- data/lib/active_job/uniqueness/{patch.rb → active_job_patch.rb} +10 -12
- data/lib/active_job/uniqueness/configuration.rb +20 -3
- data/lib/active_job/uniqueness/lock_key.rb +9 -1
- data/lib/active_job/uniqueness/lock_manager.rb +20 -4
- data/lib/active_job/uniqueness/log_subscriber.rb +68 -67
- data/lib/active_job/uniqueness/sidekiq_patch.rb +98 -0
- data/lib/active_job/uniqueness/strategies/base.rb +20 -5
- data/lib/active_job/uniqueness/strategies/until_and_while_executing.rb +9 -9
- data/lib/active_job/uniqueness/version.rb +1 -1
- data/lib/active_job/uniqueness.rb +9 -6
- data/lib/generators/active_job/uniqueness/templates/config/initializers/active_job_uniqueness.rb +11 -4
- metadata +59 -31
- data/.gitignore +0 -14
- data/.rspec +0 -3
- data/.rubocop.yml +0 -38
- data/.travis.yml +0 -22
- data/Gemfile +0 -15
- data/Rakefile +0 -8
- data/activejob-uniqueness.gemspec +0 -36
- data/lib/active_job/uniqueness/patch/sidekiq.rb +0 -93
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cd76f286ed7e6482860247e9b98b754dc1b73a381fcd2579d73e469da95d0200
|
|
4
|
+
data.tar.gz: 866f0949c68745c168217cbc70b10c65799f70aa372902dbd145781726217acd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5cb9299a82cc40a9fca3df73c771cf553ead9393b11eca505afea5e55fe3023722db67d509528d0886db66e64569ba1caea04622ebde3ca365df1d768f04d2f4
|
|
7
|
+
data.tar.gz: 205d78f3c41721bce16c16d991204423fe5429b23c1d6fad48eb1a4ac7f775057f7e15192e8d1c32c97fc0c2c4af60a1584d6a666c253df71e1acce9ba02e5fa
|
data/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,119 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
2
3
|
|
|
3
|
-
|
|
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
|
-
##
|
|
6
|
+
## [Unreleased](https://github.com/veeqo/activejob-uniqueness/compare/v0.4.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)
|
|
13
8
|
|
|
14
|
-
##
|
|
9
|
+
## [0.4.0](https://github.com/veeqo/activejob-uniqueness/compare/v0.3.2...v0.4.0) - 2024-12-07
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- [#86](https://github.com/veeqo/activejob-uniqueness/pull/86) Add Rails 8.0 rc1 support by[@sharshenov](https://github.com/sharshenov)
|
|
14
|
+
- [#78](https://github.com/veeqo/activejob-uniqueness/pull/78) Add on_redis_connection_error config to adjust to new redlock behaviour by[@nduitz](https://github.com/nduitz)
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- [#82](https://github.com/veeqo/activejob-uniqueness/pull/82) Optimize bulk unlocking [@sharshenov](https://github.com/sharshenov)
|
|
18
|
+
|
|
19
|
+
## [0.3.2](https://github.com/veeqo/activejob-uniqueness/compare/v0.3.1...v0.3.2) - 2024-08-16
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- [#80](https://github.com/veeqo/activejob-uniqueness/pull/80) Add rails 7.2 support by [@viralpraxis](https://github.com/viralpraxis)
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- [#74](https://github.com/veeqo/activejob-uniqueness/pull/74) Fix log subscriber by [@shahidkhaliq](https://github.com/shahidkhaliq)
|
|
26
|
+
|
|
27
|
+
## [0.3.1](https://github.com/veeqo/activejob-uniqueness/compare/v0.3.0...v0.3.1) - 2023-10-30
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- [#67](https://github.com/veeqo/activejob-uniqueness/pull/67) Random redis errors on delete_lock by [@laurafeier](https://github.com/laurafeier)
|
|
32
|
+
|
|
33
|
+
## [0.3.0](https://github.com/veeqo/activejob-uniqueness/compare/v0.2.5...v0.3.0) - 2023-10-20
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
- [#66](https://github.com/veeqo/activejob-uniqueness/pull/66) Activejob 7.1 support by [@laurafeier](https://github.com/laurafeier)
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- [#57](https://github.com/veeqo/activejob-uniqueness/pull/57) Upgrade to Redlock 2 & use redis-client by [@bmulholland](https://github.com/bmulholland)
|
|
40
|
+
|
|
41
|
+
### Removed
|
|
42
|
+
- Support fo Redlock v1 is removed. Switching to `RedisClient` is [a breaking change of Redlock v2](https://github.com/leandromoreira/redlock-rb/blob/main/CHANGELOG.md#200---2023-02-09).
|
|
43
|
+
|
|
44
|
+
## [0.2.5](https://github.com/veeqo/activejob-uniqueness/compare/v0.2.4...v0.2.5) - 2023-02-01
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
- [#45](https://github.com/veeqo/activejob-uniqueness/pull/45) Add Dependabot for GitHub Actions by [@petergoldstein](https://github.com/petergoldstein)
|
|
48
|
+
- [#51](https://github.com/veeqo/activejob-uniqueness/pull/51) Add support for Sidekiq 7 by [@dwightwatson](https://github.com/dwightwatson)
|
|
49
|
+
- [#52](https://github.com/veeqo/activejob-uniqueness/pull/52) Add Ruby 3.2.0 to the CI matrix by [@petergoldstein](https://github.com/petergoldstein)
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- [#46](https://github.com/veeqo/activejob-uniqueness/pull/46) Fix a method name typo in CHANGELOG by [@y-yagi](https://github.com/y-yagi)
|
|
53
|
+
|
|
54
|
+
## [0.2.4](https://github.com/veeqo/activejob-uniqueness/compare/v0.2.3...v0.2.4) - 2022-06-22
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
- [#43](https://github.com/veeqo/activejob-uniqueness/pull/43) Run rubocop on Github Actions
|
|
58
|
+
- [#44](https://github.com/veeqo/activejob-uniqueness/pull/44) Add ActiveJob::Uniqueness.reset_manager! method to reset lock manager by [@akostadinov](https://github.com/akostadinov)
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
- [#42](https://github.com/veeqo/activejob-uniqueness/pull/42) Actualize rubies and gems for tests
|
|
62
|
+
|
|
63
|
+
## [0.2.3](https://github.com/veeqo/activejob-uniqueness/compare/v0.2.2...v0.2.3) - 2022-02-28
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
- [#36](https://github.com/veeqo/activejob-uniqueness/pull/36) Support ActiveJob/Rails 7.0
|
|
67
|
+
- [#37](https://github.com/veeqo/activejob-uniqueness/pull/37) Add Ruby 3.1 to CI by [@petergoldstein](https://github.com/petergoldstein)
|
|
68
|
+
|
|
69
|
+
## [0.2.2](https://github.com/veeqo/activejob-uniqueness/compare/v0.2.1...v0.2.2) - 2021-10-22
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
- [#32](https://github.com/veeqo/activejob-uniqueness/pull/32) Add ability to set a custom runtime lock key for `:until_and_while_executing` strategy
|
|
73
|
+
|
|
74
|
+
## [0.2.1](https://github.com/veeqo/activejob-uniqueness/compare/v0.2.0...v0.2.1) - 2021-08-24
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
- [#30](https://github.com/veeqo/activejob-uniqueness/pull/30) Add Sidekiq::JobRecord support (reported by [@dwightwatson](https://github.com/dwightwatson))
|
|
78
|
+
|
|
79
|
+
## [0.2.0](https://github.com/veeqo/activejob-uniqueness/compare/v0.1.4...v0.2.0) - 2021-05-09
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
- [#22](https://github.com/veeqo/activejob-uniqueness/pull/22) Test with ruby 3.0.1
|
|
83
|
+
|
|
84
|
+
### Changed
|
|
85
|
+
- [#20](https://github.com/veeqo/activejob-uniqueness/pull/20) **Breaking** Sidekiq patch is not applied automatically anymore
|
|
86
|
+
- [#21](https://github.com/veeqo/activejob-uniqueness/pull/21) Migrate from Travis to Github Actions
|
|
87
|
+
- [#24](https://github.com/veeqo/activejob-uniqueness/pull/24) The default value for `retry_count` of redlock is now 0
|
|
88
|
+
- Require ruby 2.5+
|
|
89
|
+
|
|
90
|
+
## [0.1.4](https://github.com/veeqo/activejob-uniqueness/compare/v0.1.3...v0.1.4) - 2020-09-22
|
|
91
|
+
|
|
92
|
+
### Fixed
|
|
93
|
+
- [#11](https://github.com/veeqo/activejob-uniqueness/pull/11) Fix deprecation warnings for ruby 2.7 by [@DanAndreasson](https://github.com/DanAndreasson)
|
|
94
|
+
- [#13](https://github.com/veeqo/activejob-uniqueness/pull/13) Fix deprecation warnings for ruby 2.7
|
|
95
|
+
|
|
96
|
+
## [0.1.3](https://github.com/veeqo/activejob-uniqueness/compare/v0.1.2...v0.1.3) - 2020-08-17
|
|
97
|
+
|
|
98
|
+
### Fixed
|
|
99
|
+
- [#7](https://github.com/veeqo/activejob-uniqueness/pull/7) Fix deprecation warnings for ruby 2.7 by [@tonobo](https://github.com/tonobo)
|
|
100
|
+
|
|
101
|
+
### Changed
|
|
102
|
+
- [#8](https://github.com/veeqo/activejob-uniqueness/pull/8) Use appraisal gem to control gem versions of tests matrix
|
|
103
|
+
- [#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
|
|
104
|
+
- [#10](https://github.com/veeqo/activejob-uniqueness/pull/10) Refactor changelog to comply with Keep a Changelog
|
|
105
|
+
|
|
106
|
+
## [0.1.2](https://github.com/veeqo/activejob-uniqueness/compare/v0.1.1...v0.1.2) - 2020-07-30
|
|
107
|
+
|
|
108
|
+
### Added
|
|
109
|
+
- [#5](https://github.com/veeqo/activejob-uniqueness/pull/5) Release lock for Sidekiq adapter by [@vbyno](https://github.com/vbyno)
|
|
110
|
+
|
|
111
|
+
## [0.1.1](https://github.com/veeqo/activejob-uniqueness/compare/v0.1.0...v0.1.1) - 2020-07-23
|
|
112
|
+
|
|
113
|
+
### Fixed
|
|
114
|
+
- [#4](https://github.com/veeqo/activejob-uniqueness/pull/4) Fix `NoMethodError` on `Rails.application.eager_load!` in Rails initializer
|
|
115
|
+
|
|
116
|
+
## [0.1.0](https://github.com/veeqo/activejob-uniqueness/releases/tag/v0.1.0) - 2020-07-05
|
|
117
|
+
|
|
118
|
+
### Added
|
|
119
|
+
- Job uniqueness for ActiveJob
|
data/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Job uniqueness for ActiveJob
|
|
2
|
-
[](https://github.com/veeqo/activejob-uniqueness/actions/workflows/main.yml) [](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
|
|
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
|
|
@@ -32,29 +43,115 @@ To override the defaults, create an initializer `config/initializers/active_job_
|
|
|
32
43
|
rails generate active_job:uniqueness:install
|
|
33
44
|
```
|
|
34
45
|
|
|
46
|
+
This gem relies on `redlock` for it's Redis connection, that means **it will not inherit global configuration of `Sidekiq`**. To configure the connection, you can use `config.redlock_servers`, for example to disable SSL verification for Redis/Key-Value cloud providers:
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
ActiveJob::Uniqueness.configure do |config|
|
|
50
|
+
config.redlock_servers = [
|
|
51
|
+
RedisClient.new(
|
|
52
|
+
url: ENV['REDIS_URL'],
|
|
53
|
+
ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE }
|
|
54
|
+
)
|
|
55
|
+
]
|
|
56
|
+
end
|
|
57
|
+
```
|
|
58
|
+
|
|
35
59
|
## Usage
|
|
36
60
|
|
|
37
|
-
|
|
61
|
+
|
|
62
|
+
### Make the job to be unique
|
|
38
63
|
|
|
39
64
|
```ruby
|
|
40
65
|
class MyJob < ActiveJob::Base
|
|
66
|
+
# new jobs with the same args will raise error until existing one is executed
|
|
41
67
|
unique :until_executed
|
|
42
68
|
|
|
43
|
-
|
|
44
|
-
|
|
69
|
+
def perform(args)
|
|
70
|
+
# work
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
```
|
|
45
74
|
|
|
46
|
-
|
|
47
|
-
# unique :until_executed, on_conflict: :log
|
|
75
|
+
### Tune uniqueness settings per job
|
|
48
76
|
|
|
49
|
-
|
|
50
|
-
|
|
77
|
+
```ruby
|
|
78
|
+
class MyJob < ActiveJob::Base
|
|
79
|
+
# new jobs with the same args will be logged within 3 hours or until existing one is being executing
|
|
80
|
+
unique :until_executing, lock_ttl: 3.hours, on_conflict: :log
|
|
51
81
|
|
|
52
|
-
|
|
53
|
-
|
|
82
|
+
def perform(args)
|
|
83
|
+
# work
|
|
84
|
+
end
|
|
54
85
|
end
|
|
55
86
|
```
|
|
56
87
|
|
|
57
|
-
|
|
88
|
+
You can set defaults globally with [the configuration](#configuration)
|
|
89
|
+
|
|
90
|
+
### Control lock conflicts
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
class MyJob < ActiveJob::Base
|
|
94
|
+
# Proc gets the job instance including its arguments
|
|
95
|
+
unique :until_executing, on_conflict: ->(job) { job.logger.info "Oops: #{job.arguments}" }
|
|
96
|
+
|
|
97
|
+
def perform(args)
|
|
98
|
+
# work
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Control redis connection errors
|
|
104
|
+
|
|
105
|
+
```ruby
|
|
106
|
+
class MyJob < ActiveJob::Base
|
|
107
|
+
# Proc gets the job instance including its arguments, and as keyword arguments the resource(lock key) `resource` and the original error `error`
|
|
108
|
+
unique :until_executing, on_redis_connection_error: ->(job, resource: _, error: _) { job.logger.info "Oops: #{job.arguments}" }
|
|
109
|
+
|
|
110
|
+
def perform(args)
|
|
111
|
+
# work
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Control lock key arguments
|
|
117
|
+
|
|
118
|
+
```ruby
|
|
119
|
+
class MyJob < ActiveJob::Base
|
|
120
|
+
unique :until_executed
|
|
121
|
+
|
|
122
|
+
def perform(foo, bar, baz)
|
|
123
|
+
# work
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def lock_key_arguments
|
|
127
|
+
arguments.first(2) # baz is ignored
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Control the lock key
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
class MyJob < ActiveJob::Base
|
|
136
|
+
unique :until_executed
|
|
137
|
+
|
|
138
|
+
def perform(foo, bar, baz)
|
|
139
|
+
# work
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def lock_key
|
|
143
|
+
'qux' # completely custom lock key
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def runtime_lock_key
|
|
147
|
+
'quux' # completely custom runtime lock key for :until_and_while_executing
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Unlock jobs manually
|
|
153
|
+
|
|
154
|
+
The selected strategy automatically unlocks jobs, but in some cases (e.g. the queue is purged) it is handy to unlock jobs manually.
|
|
58
155
|
|
|
59
156
|
```ruby
|
|
60
157
|
# Remove the lock for particular arguments:
|
|
@@ -91,7 +188,30 @@ ActiveJob::Uniqueness instruments `ActiveSupport::Notifications` with next event
|
|
|
91
188
|
|
|
92
189
|
And then writes to `ActiveJob::Base.logger`.
|
|
93
190
|
|
|
94
|
-
|
|
191
|
+
**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)**
|
|
192
|
+
|
|
193
|
+
## Testing
|
|
194
|
+
|
|
195
|
+
Run redis server (in separate console):
|
|
196
|
+
```
|
|
197
|
+
docker run --rm -p 6379:6379 redis
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Run tests with:
|
|
201
|
+
|
|
202
|
+
```sh
|
|
203
|
+
bundle
|
|
204
|
+
rake
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Sidekiq API support
|
|
208
|
+
|
|
209
|
+
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.
|
|
210
|
+
Take into account that **[big queues cleanup 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:
|
|
211
|
+
|
|
212
|
+
```ruby
|
|
213
|
+
gem 'activejob-uniqueness', require: 'active_job/uniqueness/sidekiq_patch'
|
|
214
|
+
```
|
|
95
215
|
|
|
96
216
|
## Contributing
|
|
97
217
|
|
|
@@ -100,3 +220,9 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/veeqo/
|
|
|
100
220
|
## License
|
|
101
221
|
|
|
102
222
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
223
|
+
|
|
224
|
+
## About [Veeqo](https://www.veeqo.com)
|
|
225
|
+
|
|
226
|
+
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.
|
|
227
|
+
|
|
228
|
+
[Veeqo developers blog](https://devs.veeqo.com)
|
|
@@ -16,7 +16,7 @@ module ActiveJob
|
|
|
16
16
|
# end
|
|
17
17
|
# end
|
|
18
18
|
#
|
|
19
|
-
module
|
|
19
|
+
module ActiveJobPatch
|
|
20
20
|
extend ActiveSupport::Concern
|
|
21
21
|
|
|
22
22
|
class_methods do
|
|
@@ -27,6 +27,7 @@ module ActiveJob
|
|
|
27
27
|
def unique(strategy, options = {})
|
|
28
28
|
validate_on_conflict_action!(options[:on_conflict])
|
|
29
29
|
validate_on_conflict_action!(options[:on_runtime_conflict])
|
|
30
|
+
validate_on_redis_connection_error!(options[:on_redis_connection_error])
|
|
30
31
|
|
|
31
32
|
self.lock_strategy_class = ActiveJob::Uniqueness::Strategies.lookup(strategy)
|
|
32
33
|
self.lock_options = options
|
|
@@ -40,7 +41,9 @@ module ActiveJob
|
|
|
40
41
|
|
|
41
42
|
private
|
|
42
43
|
|
|
43
|
-
delegate :validate_on_conflict_action!,
|
|
44
|
+
delegate :validate_on_conflict_action!,
|
|
45
|
+
:validate_on_redis_connection_error!,
|
|
46
|
+
to: :'ActiveJob::Uniqueness.config'
|
|
44
47
|
end
|
|
45
48
|
|
|
46
49
|
included do
|
|
@@ -55,7 +58,7 @@ module ActiveJob
|
|
|
55
58
|
end
|
|
56
59
|
|
|
57
60
|
def lock_strategy
|
|
58
|
-
@lock_strategy ||= lock_strategy_class.new(
|
|
61
|
+
@lock_strategy ||= lock_strategy_class.new(job: self)
|
|
59
62
|
end
|
|
60
63
|
|
|
61
64
|
# Override in your job class if you want to customize arguments set for a digest.
|
|
@@ -64,21 +67,16 @@ module ActiveJob
|
|
|
64
67
|
end
|
|
65
68
|
|
|
66
69
|
# Override lock_key method in your job class if you want to build completely custom lock key.
|
|
67
|
-
delegate :lock_key, to: :lock_key_generator
|
|
70
|
+
delegate :lock_key, :runtime_lock_key, to: :lock_key_generator
|
|
68
71
|
|
|
69
72
|
def lock_key_generator
|
|
70
|
-
ActiveJob::Uniqueness::LockKey.new job_class_name: self.class.name,
|
|
71
|
-
|
|
73
|
+
@lock_key_generator ||= ActiveJob::Uniqueness::LockKey.new job_class_name: self.class.name,
|
|
74
|
+
arguments: lock_key_arguments
|
|
72
75
|
end
|
|
73
76
|
end
|
|
74
77
|
|
|
75
78
|
ActiveSupport.on_load(:active_job) do
|
|
76
|
-
ActiveJob::Base.include ActiveJob::Uniqueness::
|
|
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
|
|
79
|
+
ActiveJob::Base.include ActiveJob::Uniqueness::ActiveJobPatch
|
|
82
80
|
end
|
|
83
81
|
end
|
|
84
82
|
end
|
|
@@ -11,14 +11,19 @@ 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(:
|
|
17
|
+
config_accessor(:on_redis_connection_error) { :raise }
|
|
18
18
|
config_accessor(:redlock_servers) { [ENV.fetch('REDIS_URL', 'redis://localhost:6379')] }
|
|
19
|
-
config_accessor(:redlock_options) { {} }
|
|
19
|
+
config_accessor(:redlock_options) { { retry_count: 0 } }
|
|
20
20
|
config_accessor(:lock_strategies) { {} }
|
|
21
21
|
|
|
22
|
+
config_accessor(:digest_method) do
|
|
23
|
+
require 'openssl'
|
|
24
|
+
OpenSSL::Digest::MD5
|
|
25
|
+
end
|
|
26
|
+
|
|
22
27
|
def on_conflict=(action)
|
|
23
28
|
validate_on_conflict_action!(action)
|
|
24
29
|
|
|
@@ -30,6 +35,18 @@ module ActiveJob
|
|
|
30
35
|
|
|
31
36
|
raise ActiveJob::Uniqueness::InvalidOnConflictAction, "Unexpected '#{action}' action on conflict"
|
|
32
37
|
end
|
|
38
|
+
|
|
39
|
+
def on_redis_connection_error=(action)
|
|
40
|
+
validate_on_redis_connection_error!(action)
|
|
41
|
+
|
|
42
|
+
config.on_redis_connection_error = action
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def validate_on_redis_connection_error!(action)
|
|
46
|
+
return if action.nil? || action == :raise || action.respond_to?(:call)
|
|
47
|
+
|
|
48
|
+
raise ActiveJob::Uniqueness::InvalidOnConflictAction, "Unexpected '#{action}' action on_redis_connection_error"
|
|
49
|
+
end
|
|
33
50
|
end
|
|
34
51
|
end
|
|
35
52
|
end
|
|
@@ -28,11 +28,19 @@ module ActiveJob
|
|
|
28
28
|
].join(':')
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# used only by :until_and_while_executing strategy
|
|
32
|
+
def runtime_lock_key
|
|
33
|
+
[
|
|
34
|
+
lock_key,
|
|
35
|
+
'runtime'
|
|
36
|
+
].join(':')
|
|
37
|
+
end
|
|
38
|
+
|
|
31
39
|
def wildcard_key
|
|
32
40
|
[
|
|
33
41
|
lock_prefix,
|
|
34
42
|
normalized_job_class_name,
|
|
35
|
-
arguments.any? ? arguments_key_part
|
|
43
|
+
arguments.any? ? "#{arguments_key_part}*" : '*'
|
|
36
44
|
].compact.join(':')
|
|
37
45
|
end
|
|
38
46
|
|
|
@@ -9,24 +9,40 @@ module ActiveJob
|
|
|
9
9
|
# Unlocks a resource by resource only.
|
|
10
10
|
def delete_lock(resource)
|
|
11
11
|
@servers.each do |server|
|
|
12
|
-
server
|
|
13
|
-
conn.
|
|
12
|
+
synced_redis_connection(server) do |conn|
|
|
13
|
+
conn.call('DEL', resource)
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
true
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
DELETE_LOCKS_SCAN_COUNT = 1000
|
|
21
|
+
|
|
20
22
|
# Unlocks multiple resources by key wildcard.
|
|
21
23
|
def delete_locks(wildcard)
|
|
22
24
|
@servers.each do |server|
|
|
23
|
-
server
|
|
24
|
-
|
|
25
|
+
synced_redis_connection(server) do |conn|
|
|
26
|
+
cursor = 0
|
|
27
|
+
while cursor != '0'
|
|
28
|
+
cursor, keys = conn.call('SCAN', cursor, 'MATCH', wildcard, 'COUNT', DELETE_LOCKS_SCAN_COUNT)
|
|
29
|
+
conn.call('UNLINK', *keys) unless keys.empty?
|
|
30
|
+
end
|
|
25
31
|
end
|
|
26
32
|
end
|
|
27
33
|
|
|
28
34
|
true
|
|
29
35
|
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def synced_redis_connection(server, &block)
|
|
40
|
+
if server.respond_to?(:synchronize)
|
|
41
|
+
server.synchronize(&block)
|
|
42
|
+
else
|
|
43
|
+
server.instance_variable_get(:@redis).with(&block)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
30
46
|
end
|
|
31
47
|
end
|
|
32
48
|
end
|