activejob-locking 0.4.0 → 0.6.2

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
- 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
+ ```