activejob-locking 0.4.0 → 0.6.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7cd905211ccba06fbbf2fac424009b84ab5fe769
4
- data.tar.gz: c7c970994a0e5f3ad816c7b5da8ca28722d4596b
2
+ SHA256:
3
+ metadata.gz: a3908dd5b2d14cfcb98ba3c6fc4b290e63cf63ecf9e1d202dc57a881b2cde088
4
+ data.tar.gz: 904d86bca070382eac808c378fe9915f5eb5c3156ba5eff903599d6c6f229989
5
5
  SHA512:
6
- metadata.gz: 1f5f4247c8f15cd41dc0692f1a638a775229404620cee8a6318e4c410dca20e922762145fe5af991c24d71cfacc045ec9dd53f266b4bfa6d9cf22bbd4eed0e6b
7
- data.tar.gz: 7f9a485dac7c34835b7209ed3c7e2736d02ef735a8f6fc6575f8bdb9dcd2831289abe19a9d7c0823960b24a1b6eb6f74b231ac9c7408501abd9437b24d7bc912
6
+ metadata.gz: deb838dd268dd4cf13584de0ff7ee59979c400e1c0f0ffabf9852ba29fa23765f00a89871fbb4ce6daf16dc0a5d65297579da990a0c040470bcc86317aa5a835
7
+ data.tar.gz: 0e0d4f83c513aa887aede2907e304b3a6e95207ed7743882cfd0c149adc60acd93574431aef4f8a9d2c16504d1692215360e69bcb73fb6c467bc701bbca03bf9
data/Gemfile CHANGED
@@ -1,10 +1,10 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'activejob', :require => 'active_job'
4
-
5
- group :test do
6
- gem 'minitest'
7
- gem 'redis-semaphore'
8
- gem 'redlock'
9
- gem 'suo'
10
- end
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activejob', :require => 'active_job'
4
+
5
+ group :test do
6
+ gem 'minitest'
7
+ gem 'redis-semaphore'
8
+ gem 'redlock'
9
+ gem 'suo'
10
+ end
data/HISTORY.md CHANGED
@@ -1,16 +1,37 @@
1
- ## 0.3.0 (2017-06-21)
2
-
3
- - Cleanup handling of hosts
4
-
5
- ## 0.3.0 (2017-06-21)
6
-
7
- - Change lock_key signature to match perform signature
8
-
9
- ## 0.2.0 (2017-06-20)
10
-
11
- - Bug fixes
12
- - Improved tests
13
-
14
- ## 0.1.0 (2017-01-16)
15
-
16
- - Initial release
1
+ ## 0.6.2 (2020-07-12)
2
+
3
+ Fix unlock for Redlock adapter by correct deserializing keys as symbols (Volodymyr Byno)
4
+
5
+ ## 0.6.1 (2020-04-01)
6
+
7
+ - Support Rails exception discarding when deserializing (Mattias Pfeiffer)
8
+
9
+ ## 0.6.0 (2019-05-19)
10
+
11
+ - Update for Rails 6.x
12
+
13
+ ## 0.5.1 (2017-10-08)
14
+
15
+ - Loosen activejob dependency to work with ActiveJob 5.x
16
+
17
+ ## 0.5.0 (2017-10-03)
18
+
19
+ - Add enqueue_time parameter
20
+ - Fix bug in setting enqueue time
21
+
22
+ ## 0.4.0 (2017-06-21)
23
+
24
+ - Cleanup handling of hosts
25
+
26
+ ## 0.3.0 (2017-06-21)
27
+
28
+ - Change lock_key signature to match perform signature
29
+
30
+ ## 0.2.0 (2017-06-20)
31
+
32
+ - Bug fixes
33
+ - Improved tests
34
+
35
+ ## 0.1.0 (2017-01-16)
36
+
37
+ - Initial release
data/LICENSE CHANGED
@@ -1,20 +1,20 @@
1
- Copyright (c) 2017 Charlie Savage
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- Software), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2017 Charlie Savage
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ Software), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,247 +1,274 @@
1
- ActiveJob Locking
2
- ===================
3
-
4
- [![Build Status](https://secure.travis-ci.org/lantins/activejob-locking.png?branch=master)](http://travis-ci.org/cfis/activejob-locking)
5
- [![Gem Version](https://badge.fury.io/rb/activejob-locking.png)](http://badge.fury.io/rb/activejob-locking)
6
-
7
- activejob-locking lets you control how ActiveJobs are enqueued and performed:
8
-
9
- * Allow only one job to be enqueued at a time - thus a "unique" job
10
- * Allow only one job to be performed at a time - thus a "serialized" job
11
-
12
- There are many other similar gems including [resque-lock-timeout](https://github.com/lantins/resque-lock-timeout),
13
- [activejob-traffic-control](https://github.com/nickelser/activejob-traffic_control), [activejob-lock](https://github.com/idolweb/activejob-lock),
14
- [activejob-locks](https://github.com/erickrause/activejob-locks). What is different about this gem is that it
15
- is agnostic on the locking mechanism. In the same way that ActiveJob works with many apapters, ActiveJob Locking
16
- works with a variety of locking gems.
17
-
18
- Installation
19
- ------------
20
-
21
- Add this line to your application's Gemfile:
22
-
23
- ```ruby
24
- gem 'activejob-locking'
25
- ```
26
-
27
- Unique Jobs
28
- ------------
29
- Sometime you only want to enqueue one instance of a job. No other similar job should be enqueued until the first one
30
- is completed.
31
-
32
- ```ruby
33
- class UniqueJob < ActiveJob::Base
34
- include ActiveJob::Locking::Unique
35
-
36
- # Make sure the lock_key is always the same
37
- def lock_key(object)
38
- self.class.name
39
- end
40
-
41
- def perform(object)
42
- # do some work
43
- end
44
- end
45
- ```
46
- Only one instance of this job will ever be enqueued. If an additional job is enqueued, it will either be dropped and
47
- never be enqueued or it will wait to the first job is performed. That is controlled by the job
48
- [options](##options) described below.
49
-
50
-
51
- Serialized Jobs
52
- ------------
53
- Sometime you only want to perform one instance of a job at a time. No other similar job should be performed until the first one
54
- is completed.
55
-
56
- ```ruby
57
- class SerializedJob < ActiveJob::Base
58
- include ActiveJob::Locking::Serialized
59
-
60
- # Make sure the lock_key is always the same
61
- def lock_key
62
- self.class.name
63
- end
64
-
65
- def perform
66
- # do some work
67
- end
68
- end
69
- ```
70
- Only one instance of this job will ever be performed. If an additional job is enqueued, it will wait in its que until
71
- to the first job is performed.
72
-
73
- Locking
74
- ------------
75
- Locks are used to control how jobs are enqueued and performed. The idea is that locks are stored in a distributed
76
- system such as [Redis](https://redis.io/) or [Memcached](https://memcached.org/) so they can be used by
77
- multiple servers to coordinate the enqueueing and performing of jobs.
78
-
79
- The ActiveJob Locking gem does not include a locking implementation. Instead it provides adapters for
80
- distributed locking gems.
81
-
82
- Currently three gems are supported:
83
-
84
- * [redis-semaphore](https://github.com/dv/redis-semaphore)
85
-
86
- * [suo](https://github.com/nickelser/suo)
87
-
88
- * [redlock-rb](https://github.com/leandromoreira/redlock-rb)
89
-
90
- If you would like to have an additional locking mechanism supported, please feel free to send in a pull request.
91
-
92
- Please see the [options](##options) section below on how to specify a locking adapter.
93
-
94
-
95
- Lock Key
96
- ---------
97
-
98
- Notice that the code samples above include a `lock_key` method. The return value of this method is used by the
99
- gem to create locks behind the scenes. Thus it holds the key (pun intended) to controlling how jobs are enqueued
100
- and performed.
101
-
102
- By default the key is defined as:
103
-
104
- ```ruby
105
- def lock_key(*args)
106
- [self.class.name, serialize_arguments(self.arguments)].join('/')
107
- end
108
- ```
109
- Thus it has the format `<job class name>/<serialized_job_arguments>`
110
-
111
- The args passed to the lock key method are the same that are passed to the job's perform method.
112
-
113
- To use this gem, you will want to override this method per job.
114
-
115
- ### Examples
116
-
117
- Allow only one job per queue to be enqueued or performed:
118
-
119
- ```ruby
120
- def lock_key(*args)
121
- self.queue
122
- end
123
- ```
124
-
125
- Allow only one instance of a job class to be enqueued of performed:
126
-
127
- ```ruby
128
- def lock_key(*args)
129
- self.class.name
130
- end
131
- ```
132
-
133
- Options
134
- -------
135
- The locking behavior can be dramatically changed by tweaking various options. There is a global set of options
136
- available at:
137
-
138
- ```ruby
139
- ActiveJob::Locking.options
140
- ```
141
- This should be updated using a Rails initializer. Each job class can override individual options as it sees fit.
142
-
143
- ### Adapter
144
-
145
- Use the adapter option to specify which locking gem to use.
146
-
147
- Globally update:
148
-
149
- ```ruby
150
- ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::SuoRedis
151
- ```
152
- Locally update:
153
-
154
- ```ruby
155
- class ExampleJob < ActiveJob::Base
156
- include ActiveJob::Locking::Serialized
157
-
158
- self.adapter = ActiveJob::Locking::Adapters::SuoRedis
159
- end
160
- ```
161
-
162
- ### Hosts
163
-
164
- An array of hosts for the distributed system. This format is dependent on the locking gem, but generally is a url or an existing Memcache or Redis
165
- connection. Please refer to the appropriate locking gem's documentation documentation.
166
-
167
- Globally update:
168
-
169
- ```ruby
170
- ActiveJob::Locking.options.hosts = ['localhost']
171
- ```
172
- Locally update:
173
-
174
- ```ruby
175
- class ExampleJob < ActiveJob::Base
176
- include ActiveJob::Locking::Serialized
177
-
178
- self.hosts = ['localhost']
179
- end
180
- ```
181
-
182
- ### lock_acquire_time
183
-
184
- The is the timeout for acquiring a lock. The value is specified in seconds and defaults to 1. It must
185
- be greater than zero and cannot be nil.
186
-
187
- Globally update:
188
-
189
- ```ruby
190
- ActiveJob::Locking.options.lock_acquire_time = 1
191
- ```
192
- Locally update:
193
-
194
- ```ruby
195
- class ExampleJob < ActiveJob::Base
196
- include ActiveJob::Locking::Unique
197
-
198
- self.lock_acquire_time = 1
199
- end
200
- ```
201
- This greatly influences how enqueuing behavior works. If the timeout is short, then jobs that are waiting to
202
- be enqueued are dropped and the before_enqueue callback will fail. If the timeout is infinite, then jobs will wait
203
- in turn to get enqueued. If the timeout is somewhere in between then it will depend on how long the jobs
204
- take to execute.
205
-
206
- ### lock_time
207
-
208
- The is the time to live for any acquired locks. For most locking gems this is mapped to their concept of "stale" locks.
209
- That means that if an attempt is made to access the lock after it is expired, it will be considered unlocked. That is in
210
- contrast to aggressively removing locks for running jobs even if no other job has requested them.
211
-
212
- The value is specified in seconds and defaults to 100.
213
-
214
- Globally update:
215
-
216
- ```ruby
217
- ActiveJob::Locking.options.lock_time = 100
218
- ```
219
- Locally update:
220
-
221
- ```ruby
222
- class ExampleJob < ActiveJob::Base
223
- include ActiveJob::Locking::Serialized
224
-
225
- self.lock_time = 100
226
- end
227
- ```
228
-
229
- ### AdapterOptions
230
-
231
- This is a hash table of options that should be sent to the lock gem when it is instantiated. Read the lock
232
- gems documentation to find appropriate values.
233
-
234
- Globally update:
235
-
236
- ```ruby
237
- ActiveJob::Locking.options.adapter_options = {}
238
- ```
239
- Locally update (notice the different method name to avoid potential conflicts):
240
-
241
- ```ruby
242
- class ExampleJob < ActiveJob::Base
243
- include ActiveJob::Locking::Unique
244
-
245
- self.adapter_options = {}
246
- end
247
- ```
1
+ ActiveJob Locking
2
+ ===================
3
+
4
+ [![Build Status](https://secure.travis-ci.org/lantins/activejob-locking.png?branch=master)](http://travis-ci.org/cfis/activejob-locking)
5
+ [![Gem Version](https://badge.fury.io/rb/activejob-locking.png)](http://badge.fury.io/rb/activejob-locking)
6
+
7
+ activejob-locking lets you control how ActiveJobs are enqueued and performed:
8
+
9
+ * Allow only one job to be enqueued at a time - thus a "unique" job
10
+ * Allow only one job to be performed at a time - thus a "serialized" job
11
+
12
+ There are many other similar gems including [resque-lock-timeout](https://github.com/lantins/resque-lock-timeout),
13
+ [activejob-traffic-control](https://github.com/nickelser/activejob-traffic_control), [activejob-lock](https://github.com/idolweb/activejob-lock),
14
+ [activejob-locks](https://github.com/erickrause/activejob-locks). What is different about this gem is that it
15
+ is agnostic on the locking mechanism. In the same way that ActiveJob works with many apapters, ActiveJob Locking
16
+ works with a variety of locking gems.
17
+
18
+ Installation
19
+ ------------
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ ```ruby
24
+ gem 'activejob-locking'
25
+ ```
26
+
27
+ Unique Jobs
28
+ ------------
29
+ Sometime you only want to enqueue one instance of a job. No other similar job should be enqueued until the first one
30
+ is completed.
31
+
32
+ ```ruby
33
+ class UniqueJob < ActiveJob::Base
34
+ include ActiveJob::Locking::Unique
35
+
36
+ # Make sure the lock_key is always the same
37
+ def lock_key(object)
38
+ self.class.name
39
+ end
40
+
41
+ def perform(object)
42
+ # do some work
43
+ end
44
+ end
45
+ ```
46
+ Only one instance of this job will ever be enqueued. If an additional job is enqueued, it will either be dropped and
47
+ never be enqueued or it will wait to the first job is performed. That is controlled by the job
48
+ [options](##options) described below.
49
+
50
+
51
+ Serialized Jobs
52
+ ------------
53
+ Sometime you only want to perform one instance of a job at a time. No other similar job should be performed until the first one
54
+ is completed.
55
+
56
+ ```ruby
57
+ class SerializedJob < ActiveJob::Base
58
+ include ActiveJob::Locking::Serialized
59
+
60
+ # Make sure the lock_key is always the same
61
+ def lock_key
62
+ self.class.name
63
+ end
64
+
65
+ def perform
66
+ # do some work
67
+ end
68
+ end
69
+ ```
70
+ Only one instance of this job will ever be performed. If an additional job is enqueued, it will wait in its que until
71
+ to the first job is performed.
72
+
73
+ Locking
74
+ ------------
75
+ Locks are used to control how jobs are enqueued and performed. The idea is that locks are stored in a distributed
76
+ system such as [Redis](https://redis.io/) or [Memcached](https://memcached.org/) so they can be used by
77
+ multiple servers to coordinate the enqueueing and performing of jobs.
78
+
79
+ The ActiveJob Locking gem does not include a locking implementation. Instead it provides adapters for
80
+ distributed locking gems.
81
+
82
+ Currently three gems are supported:
83
+
84
+ * [redis-semaphore](https://github.com/dv/redis-semaphore)
85
+
86
+ * [suo](https://github.com/nickelser/suo)
87
+
88
+ * [redlock-rb](https://github.com/leandromoreira/redlock-rb)
89
+
90
+ If you would like to have an additional locking mechanism supported, please feel free to send in a pull request.
91
+
92
+ Please see the [options](##options) section below on how to specify a locking adapter.
93
+
94
+
95
+ Lock Key
96
+ ---------
97
+
98
+ Notice that the code samples above include a `lock_key` method. The return value of this method is used by the
99
+ gem to create locks behind the scenes. Thus it holds the key (pun intended) to controlling how jobs are enqueued
100
+ and performed.
101
+
102
+ By default the key is defined as:
103
+
104
+ ```ruby
105
+ def lock_key(*args)
106
+ [self.class.name, serialize_arguments(self.arguments)].join('/')
107
+ end
108
+ ```
109
+ Thus it has the format `<job class name>/<serialized_job_arguments>`
110
+
111
+ The args passed to the lock key method are the same that are passed to the job's perform method.
112
+
113
+ To use this gem, you will want to override this method per job.
114
+
115
+ ### Examples
116
+
117
+ Allow only one job per queue to be enqueued or performed:
118
+
119
+ ```ruby
120
+ def lock_key(*args)
121
+ self.queue
122
+ end
123
+ ```
124
+
125
+ Allow only one instance of a job class to be enqueued of performed:
126
+
127
+ ```ruby
128
+ def lock_key(*args)
129
+ self.class.name
130
+ end
131
+ ```
132
+
133
+ Options
134
+ -------
135
+ The locking behavior can be dramatically changed by tweaking various options. There is a global set of options
136
+ available at:
137
+
138
+ ```ruby
139
+ ActiveJob::Locking.options
140
+ ```
141
+ This should be updated using a Rails initializer. Each job class can override individual options as it sees fit.
142
+
143
+ ### Adapter
144
+
145
+ Use the adapter option to specify which locking gem to use.
146
+
147
+ Globally update:
148
+
149
+ ```ruby
150
+ ActiveJob::Locking.options.adapter = ActiveJob::Locking::Adapters::SuoRedis
151
+ ```
152
+ Locally update:
153
+
154
+ ```ruby
155
+ class ExampleJob < ActiveJob::Base
156
+ include ActiveJob::Locking::Serialized
157
+
158
+ self.adapter = ActiveJob::Locking::Adapters::SuoRedis
159
+ end
160
+ ```
161
+
162
+ ### Hosts
163
+
164
+ An array of hosts for the distributed system. This format is dependent on the locking gem, but generally is a url or an existing Memcache or Redis
165
+ connection. Please refer to the appropriate locking gem's documentation documentation.
166
+
167
+ Globally update:
168
+
169
+ ```ruby
170
+ ActiveJob::Locking.options.hosts = ['localhost']
171
+ ```
172
+ Locally update:
173
+
174
+ ```ruby
175
+ class ExampleJob < ActiveJob::Base
176
+ include ActiveJob::Locking::Serialized
177
+
178
+ self.hosts = ['localhost']
179
+ end
180
+ ```
181
+
182
+ ### lock_time
183
+
184
+ The is the time to live for any acquired locks. For most locking gems this is mapped to their concept of "stale" locks.
185
+ That means that if an attempt is made to access the lock after it is expired, it will be considered unlocked. That is in
186
+ contrast to aggressively removing locks for running jobs even if no other job has requested them.
187
+
188
+ The value is specified in seconds and defaults to 100.
189
+
190
+ Globally update:
191
+
192
+ ```ruby
193
+ ActiveJob::Locking.options.lock_time = 100
194
+ ```
195
+ Locally update:
196
+
197
+ ```ruby
198
+ class ExampleJob < ActiveJob::Base
199
+ include ActiveJob::Locking::Serialized
200
+
201
+ self.lock_time = 100
202
+ end
203
+ ```
204
+
205
+ You almost surely want the lock_time to be greater than the time it takes to execute the job. Otherwise, the lock will expire
206
+ and extra jobs will start to run. When the job finishes, or fails, the lock will be released. However, remember that the job
207
+ could be terminated by the operating system or a monitoring system (such as monit). In that case, the lock won't be released
208
+ and will remain in force until its lock_time expires.
209
+
210
+ ### lock_acquire_time
211
+
212
+ The is the timeout for acquiring a lock. The value is specified in seconds and defaults to 1. It must
213
+ be greater than zero and cannot be nil.
214
+
215
+ Globally update:
216
+
217
+ ```ruby
218
+ ActiveJob::Locking.options.lock_acquire_time = 1
219
+ ```
220
+ Locally update:
221
+
222
+ ```ruby
223
+ class ExampleJob < ActiveJob::Base
224
+ include ActiveJob::Locking::Unique
225
+
226
+ self.lock_acquire_time = 1
227
+ end
228
+ ```
229
+
230
+ Remember that most locking gems block the current thread when trying to acquire a lock. Therefore you likely want
231
+ lock_acquire_time to be low. However, the lower it is the more likely that unique jobs that are enqueued will
232
+ expire and be dropped.
233
+
234
+ ### enqueue_time
235
+
236
+ The is the time to re-enqueue a job if the lock_time has expired. Thus this value is only relevant for
237
+ serialized jobs since unique jobs will be dropped instead of enqueded.
238
+
239
+ The value is specified in seconds and defaults to 100.
240
+
241
+ Globally update:
242
+
243
+ ```ruby
244
+ ActiveJob::Locking.options.enqueue_time = 100
245
+ ```
246
+ Locally update:
247
+
248
+ ```ruby
249
+ class ExampleJob < ActiveJob::Base
250
+ include ActiveJob::Locking::Serialized
251
+
252
+ self.enqueue_time = 100
253
+ end
254
+ ```
255
+
256
+ ### AdapterOptions
257
+
258
+ This is a hash table of options that should be sent to the lock gem when it is instantiated. Read the lock
259
+ gems documentation to find appropriate values.
260
+
261
+ Globally update:
262
+
263
+ ```ruby
264
+ ActiveJob::Locking.options.adapter_options = {}
265
+ ```
266
+ Locally update (notice the different method name to avoid potential conflicts):
267
+
268
+ ```ruby
269
+ class ExampleJob < ActiveJob::Base
270
+ include ActiveJob::Locking::Unique
271
+
272
+ self.adapter_options = {}
273
+ end
274
+ ```