resque-lock-timeout 0.4.1 → 0.4.4
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 +7 -0
- data/HISTORY.md +5 -0
- data/README.md +16 -11
- data/lib/resque/plugins/lock_timeout.rb +24 -1
- data/test/lock_test.rb +28 -5
- data/test/test_helper.rb +10 -13
- metadata +37 -74
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6fc8ebf154ea6508ebd762f6860002c07f70412d
|
4
|
+
data.tar.gz: 7053ff9081baa02832267aeb5739ec9d46317269
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 590c45f94ec0dc1b40612a94b7545b7c01964eeced9e7ce0d5b0e4f0af4763cdca0223fc991e6c66c03cb462a497a31fb1cb28aa611673153e2cbcd83ed343a0
|
7
|
+
data.tar.gz: c678088940a1857169695fa0907dad6b9cf9839c3f9f571c974128dfcebef92dba36e960a5143452ce515d7542e74eb99004e5590be9f14cc8207e3e23e8e091
|
data/HISTORY.md
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
Resque Lock Timeout
|
2
2
|
===================
|
3
3
|
|
4
|
+
[](http://travis-ci.org/lantins/resque-lock-timeout)
|
5
|
+
[](http://badge.fury.io/rb/resque-lock-timeout)
|
6
|
+
|
4
7
|
A [Resque][rq] plugin. Requires Resque >= v1.8.0.
|
5
8
|
|
6
9
|
resque-lock-timeout adds locking, with optional timeout/deadlock handling to
|
7
10
|
resque jobs.
|
8
11
|
|
9
12
|
Using a `lock_timeout` allows you to re-acquire the lock should your worker
|
10
|
-
fail, crash, or is otherwise unable to
|
11
|
-
unexpectedly
|
13
|
+
fail, crash, or is otherwise unable to release the lock. **i.e.** Your server
|
14
|
+
unexpectedly loses power. Very handy for jobs that are recurring or may be
|
12
15
|
retried.
|
13
16
|
|
14
17
|
Usage / Examples
|
@@ -27,15 +30,15 @@ Usage / Examples
|
|
27
30
|
end
|
28
31
|
end
|
29
32
|
|
30
|
-
Locking is achieved by storing a
|
33
|
+
Locking is achieved by storing a identifier/lock key in Redis.
|
31
34
|
|
32
|
-
Default
|
35
|
+
Default behavior...
|
33
36
|
|
34
37
|
* Only one instance of a job may execute at once.
|
35
38
|
* The lock is held until the job completes or fails.
|
36
39
|
* If another job is executing with the same arguments the job will abort.
|
37
40
|
|
38
|
-
Please see below for more information about the
|
41
|
+
Please see below for more information about the identifier/lock key.
|
39
42
|
|
40
43
|
### Enqueued Exclusivity (Loner Option)
|
41
44
|
|
@@ -64,7 +67,7 @@ Simply set the lock timeout in seconds, e.g.
|
|
64
67
|
extend Resque::Plugins::LockTimeout
|
65
68
|
@queue = :network_graph
|
66
69
|
|
67
|
-
# Lock may be held for
|
70
|
+
# Lock may be held for up to an hour.
|
68
71
|
@lock_timeout = 3600
|
69
72
|
|
70
73
|
def self.perform(repo_id)
|
@@ -72,7 +75,7 @@ Simply set the lock timeout in seconds, e.g.
|
|
72
75
|
end
|
73
76
|
end
|
74
77
|
|
75
|
-
|
78
|
+
Customize & Extend
|
76
79
|
==================
|
77
80
|
|
78
81
|
### Job Identifier/Lock Key
|
@@ -160,6 +163,8 @@ using job arguments. e.g.
|
|
160
163
|
### Helper Methods
|
161
164
|
|
162
165
|
* `locked?` - checks if the lock is currently held.
|
166
|
+
* `enqueued?` - checks if the loner lock is currently held.
|
167
|
+
* `loner_locked?` - checks if the job is either enqueued (if a loner) or locked (any job).
|
163
168
|
* `refresh_lock!` - Refresh the lock, useful for jobs that are taking longer
|
164
169
|
then usual but your okay with them holding on to the lock a little longer.
|
165
170
|
|
@@ -171,7 +176,7 @@ Several callbacks are available to override and implement your own logic, e.g.
|
|
171
176
|
extend Resque::Plugins::Lock
|
172
177
|
@queue = :network_graph
|
173
178
|
|
174
|
-
# Lock may be held for
|
179
|
+
# Lock may be held for up to an hour.
|
175
180
|
@lock_timeout = 3600
|
176
181
|
|
177
182
|
# No same job get enqueued if one already running/enqueued
|
@@ -187,7 +192,7 @@ Several callbacks are available to override and implement your own logic, e.g.
|
|
187
192
|
raise EnqueueFailed
|
188
193
|
end
|
189
194
|
|
190
|
-
# Job has complete; but the lock expired before we could
|
195
|
+
# Job has complete; but the lock expired before we could release it.
|
191
196
|
# The lock wasn't released; as its *possible* the lock is now held
|
192
197
|
# by another job.
|
193
198
|
def self.lock_expired_before_release(repo_id)
|
@@ -212,6 +217,6 @@ Lock timeout from Ryan Carvar' [resque-lock-retry][resque-lock-retry] plugin.
|
|
212
217
|
And a little tinkering from Luke Antins.
|
213
218
|
|
214
219
|
[rq]: http://github.com/defunkt/resque
|
215
|
-
[redis-setnx]: http://
|
220
|
+
[redis-setnx]: http://redis.io/commands/setnx
|
216
221
|
[resque-lock]: http://github.com/defunkt/resque-lock
|
217
|
-
[resque-lock-retry]: http://github.com/rcarver/resque-lock-retry
|
222
|
+
[resque-lock-retry]: http://github.com/rcarver/resque-lock-retry
|
@@ -110,11 +110,34 @@ module Resque
|
|
110
110
|
@loner ||= false
|
111
111
|
end
|
112
112
|
|
113
|
+
# Checks if job is locked or loner locked (if applicable).
|
114
|
+
#
|
115
|
+
# @return [Boolean] true if the job is locked by someone
|
116
|
+
def loner_locked?(*args)
|
117
|
+
locked?(*args) || (loner && enqueued?(*args))
|
118
|
+
end
|
119
|
+
|
113
120
|
# Convenience method to check if job is locked and lock did not expire.
|
114
121
|
#
|
115
122
|
# @return [Boolean] true if the job is locked by someone
|
116
123
|
def locked?(*args)
|
117
|
-
|
124
|
+
inspect_lock(:redis_lock_key, *args)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Convenience method to check if a loner job is queued and lock did not expire.
|
128
|
+
#
|
129
|
+
# @return [Boolean] true if the job is already queued
|
130
|
+
def enqueued?(*args)
|
131
|
+
inspect_lock(:redis_loner_lock_key, *args)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Check for existence of given key.
|
135
|
+
#
|
136
|
+
# @param [Array] args job arguments
|
137
|
+
# @param [Symbol] lock_key_method the method returning redis key to lock
|
138
|
+
# @return [Boolean] true if the lock exists
|
139
|
+
def inspect_lock(lock_key_method, *args)
|
140
|
+
lock_until = lock_redis.get(self.send(lock_key_method, *args))
|
118
141
|
return (lock_until.to_i > Time.now.to_i) if lock_timeout(*args) > 0
|
119
142
|
!lock_until.nil?
|
120
143
|
end
|
data/test/lock_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
|
-
class LockTest <
|
3
|
+
class LockTest < Minitest::Test
|
4
4
|
def setup
|
5
5
|
$success = $lock_failed = $lock_expired = $enqueue_failed = 0
|
6
6
|
Resque.redis.flushall
|
@@ -157,15 +157,27 @@ class LockTest < MiniTest::Unit::TestCase
|
|
157
157
|
end
|
158
158
|
|
159
159
|
def test_cannot_enqueue_two_loner_jobs
|
160
|
-
Resque.enqueue(LonelyJob)
|
161
|
-
Resque.enqueue(LonelyJob)
|
160
|
+
assert Resque.enqueue(LonelyJob)
|
161
|
+
assert !Resque.enqueue(LonelyJob)
|
162
162
|
assert_equal 1, Resque.size(:test), '1 job should be enqueued'
|
163
163
|
|
164
|
-
Resque.enqueue(LonelyTimeoutJob)
|
165
|
-
Resque.enqueue(LonelyTimeoutJob)
|
164
|
+
assert Resque.enqueue(LonelyTimeoutJob)
|
165
|
+
assert !Resque.enqueue(LonelyTimeoutJob)
|
166
166
|
assert_equal 2, Resque.size(:test), '2 jobs should be enqueued'
|
167
167
|
end
|
168
168
|
|
169
|
+
def test_queue_inspection
|
170
|
+
Resque.enqueue(LonelyJob)
|
171
|
+
assert !LonelyJob.locked?, 'job is still in queue'
|
172
|
+
assert LonelyJob.loner_locked?, 'loner key should have been set'
|
173
|
+
assert LonelyJob.enqueued?, 'loner key should have been set'
|
174
|
+
|
175
|
+
Resque.enqueue(SlowJob)
|
176
|
+
assert !SlowJob.locked?, 'job is still in queue'
|
177
|
+
assert !SlowJob.loner_locked?, 'no loner lock key should hae been created'
|
178
|
+
assert !SlowJob.enqueued?, 'no loner lock key should hae been created'
|
179
|
+
end
|
180
|
+
|
169
181
|
def test_loner_job_should_not_be_enqued_if_already_running
|
170
182
|
Resque.enqueue(LonelyJob)
|
171
183
|
thread = Thread.new { @worker.process }
|
@@ -202,4 +214,15 @@ class LockTest < MiniTest::Unit::TestCase
|
|
202
214
|
assert_equal 1, Resque.size(:test), "Should be able to enqueue a loner job if one previously finished after the timeout"
|
203
215
|
end
|
204
216
|
|
217
|
+
def test_loner_job_should_get_enqueued_if_previous_inline_job_finished
|
218
|
+
Resque.inline = true
|
219
|
+
Resque.enqueue(LonelyJob)
|
220
|
+
Resque.inline = false
|
221
|
+
|
222
|
+
sleep 0.5
|
223
|
+
|
224
|
+
assert_equal 0, Resque.size(:test), "Nothing should be in the queue"
|
225
|
+
Resque.enqueue(LonelyJob)
|
226
|
+
assert_equal 1, Resque.size(:test), "Should have enqueued the job"
|
227
|
+
end
|
205
228
|
end
|
data/test/test_helper.rb
CHANGED
@@ -2,10 +2,6 @@ dir = File.dirname(File.expand_path(__FILE__))
|
|
2
2
|
$LOAD_PATH.unshift dir + '/../lib'
|
3
3
|
$TESTING = true
|
4
4
|
|
5
|
-
require 'rubygems'
|
6
|
-
require 'minitest/unit'
|
7
|
-
require 'minitest/pride'
|
8
|
-
|
9
5
|
# Run code coverage in MRI 1.9 only.
|
10
6
|
if RUBY_VERSION >= '1.9' && RUBY_ENGINE == 'ruby'
|
11
7
|
require 'simplecov'
|
@@ -14,6 +10,9 @@ if RUBY_VERSION >= '1.9' && RUBY_ENGINE == 'ruby'
|
|
14
10
|
end
|
15
11
|
end
|
16
12
|
|
13
|
+
require 'minitest/pride'
|
14
|
+
require 'minitest/autorun'
|
15
|
+
|
17
16
|
require 'resque-lock-timeout'
|
18
17
|
require dir + '/test_jobs'
|
19
18
|
|
@@ -29,15 +28,13 @@ if !system('which redis-cli')
|
|
29
28
|
abort ''
|
30
29
|
end
|
31
30
|
|
32
|
-
# This code is run `at_exit` to setup everything before running the tests.
|
33
|
-
# Redis server is started before this code block runs.
|
34
|
-
at_exit do
|
35
|
-
next if $!
|
36
|
-
|
37
|
-
exit_code = MiniTest::Unit.new.run(ARGV)
|
38
|
-
`redis-cli -p 9737 shutdown nosave`
|
39
|
-
end
|
40
|
-
|
41
31
|
puts "Starting redis for testing at localhost:9737..."
|
32
|
+
|
33
|
+
# Start redis server for testing.
|
42
34
|
`redis-server #{dir}/redis-test.conf`
|
43
35
|
Resque.redis = '127.0.0.1:9737'
|
36
|
+
|
37
|
+
# After tests are complete, make sure we shutdown redis.
|
38
|
+
Minitest.after_run {
|
39
|
+
`redis-cli -p 9737 shutdown nosave`
|
40
|
+
}
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-lock-timeout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Luke Antins
|
@@ -11,121 +10,85 @@ authors:
|
|
11
10
|
autorequire:
|
12
11
|
bindir: bin
|
13
12
|
cert_chain: []
|
14
|
-
date:
|
13
|
+
date: 2014-02-21 00:00:00.000000000 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: resque
|
18
17
|
requirement: !ruby/object:Gem::Requirement
|
19
|
-
none: false
|
20
18
|
requirements:
|
21
|
-
- -
|
19
|
+
- - "~>"
|
22
20
|
- !ruby/object:Gem::Version
|
23
|
-
version: 1.
|
21
|
+
version: '1.22'
|
24
22
|
type: :runtime
|
25
23
|
prerelease: false
|
26
24
|
version_requirements: !ruby/object:Gem::Requirement
|
27
|
-
none: false
|
28
25
|
requirements:
|
29
|
-
- -
|
26
|
+
- - "~>"
|
30
27
|
- !ruby/object:Gem::Version
|
31
|
-
version: 1.
|
28
|
+
version: '1.22'
|
32
29
|
- !ruby/object:Gem::Dependency
|
33
30
|
name: rake
|
34
31
|
requirement: !ruby/object:Gem::Requirement
|
35
|
-
none: false
|
36
32
|
requirements:
|
37
|
-
- -
|
33
|
+
- - ">="
|
38
34
|
- !ruby/object:Gem::Version
|
39
35
|
version: '0'
|
40
36
|
type: :development
|
41
37
|
prerelease: false
|
42
38
|
version_requirements: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
39
|
requirements:
|
45
|
-
- -
|
40
|
+
- - ">="
|
46
41
|
- !ruby/object:Gem::Version
|
47
42
|
version: '0'
|
48
43
|
- !ruby/object:Gem::Dependency
|
49
44
|
name: minitest
|
50
45
|
requirement: !ruby/object:Gem::Requirement
|
51
|
-
none: false
|
52
46
|
requirements:
|
53
|
-
- -
|
47
|
+
- - "~>"
|
54
48
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
49
|
+
version: '5.2'
|
56
50
|
type: :development
|
57
51
|
prerelease: false
|
58
52
|
version_requirements: !ruby/object:Gem::Requirement
|
59
|
-
none: false
|
60
53
|
requirements:
|
61
|
-
- -
|
54
|
+
- - "~>"
|
62
55
|
- !ruby/object:Gem::Version
|
63
|
-
version: '
|
64
|
-
- !ruby/object:Gem::Dependency
|
65
|
-
name: json
|
66
|
-
requirement: !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
|
-
requirements:
|
69
|
-
- - ! '>='
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
version: '0'
|
72
|
-
type: :development
|
73
|
-
prerelease: false
|
74
|
-
version_requirements: !ruby/object:Gem::Requirement
|
75
|
-
none: false
|
76
|
-
requirements:
|
77
|
-
- - ! '>='
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
version: '0'
|
56
|
+
version: '5.2'
|
80
57
|
- !ruby/object:Gem::Dependency
|
81
58
|
name: yard
|
82
59
|
requirement: !ruby/object:Gem::Requirement
|
83
|
-
none: false
|
84
|
-
requirements:
|
85
|
-
- - ! '>='
|
86
|
-
- !ruby/object:Gem::Version
|
87
|
-
version: '0'
|
88
|
-
type: :development
|
89
|
-
prerelease: false
|
90
|
-
version_requirements: !ruby/object:Gem::Requirement
|
91
|
-
none: false
|
92
|
-
requirements:
|
93
|
-
- - ! '>='
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: '0'
|
96
|
-
- !ruby/object:Gem::Dependency
|
97
|
-
name: rdiscount
|
98
|
-
requirement: !ruby/object:Gem::Requirement
|
99
|
-
none: false
|
100
60
|
requirements:
|
101
|
-
- -
|
61
|
+
- - "~>"
|
102
62
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
63
|
+
version: '0.8'
|
104
64
|
type: :development
|
105
65
|
prerelease: false
|
106
66
|
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
none: false
|
108
67
|
requirements:
|
109
|
-
- -
|
68
|
+
- - "~>"
|
110
69
|
- !ruby/object:Gem::Version
|
111
|
-
version: '0'
|
70
|
+
version: '0.8'
|
112
71
|
- !ruby/object:Gem::Dependency
|
113
72
|
name: simplecov
|
114
73
|
requirement: !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
74
|
requirements:
|
117
|
-
- -
|
75
|
+
- - "~>"
|
118
76
|
- !ruby/object:Gem::Version
|
119
|
-
version: 0.
|
77
|
+
version: '0.7'
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 0.7.1
|
120
81
|
type: :development
|
121
82
|
prerelease: false
|
122
83
|
version_requirements: !ruby/object:Gem::Requirement
|
123
|
-
none: false
|
124
84
|
requirements:
|
125
|
-
- -
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0.7'
|
88
|
+
- - ">="
|
126
89
|
- !ruby/object:Gem::Version
|
127
|
-
version: 0.
|
128
|
-
description:
|
90
|
+
version: 0.7.1
|
91
|
+
description: " A Resque plugin. Adds locking, with optional timeout/deadlock handling
|
129
92
|
to\n resque jobs.\n\n Using a `lock_timeout` allows you to re-acquire the lock
|
130
93
|
should your worker\n fail, crash, or is otherwise unable to relase the lock.\n
|
131
94
|
\ \n i.e. Your server unexpectedly looses power. Very handy for jobs that are\n
|
@@ -135,39 +98,39 @@ executables: []
|
|
135
98
|
extensions: []
|
136
99
|
extra_rdoc_files: []
|
137
100
|
files:
|
101
|
+
- HISTORY.md
|
102
|
+
- LICENSE
|
138
103
|
- README.md
|
139
104
|
- Rakefile
|
140
|
-
- LICENSE
|
141
|
-
- HISTORY.md
|
142
|
-
- lib/resque/plugins/lock_timeout.rb
|
143
105
|
- lib/resque-lock-timeout.rb
|
106
|
+
- lib/resque/plugins/lock_timeout.rb
|
144
107
|
- test/lock_test.rb
|
145
108
|
- test/redis-test.conf
|
146
109
|
- test/test_helper.rb
|
147
110
|
- test/test_jobs.rb
|
148
111
|
homepage: http://github.com/lantins/resque-lock-timeout
|
149
|
-
licenses:
|
112
|
+
licenses:
|
113
|
+
- MIT
|
114
|
+
metadata: {}
|
150
115
|
post_install_message:
|
151
116
|
rdoc_options: []
|
152
117
|
require_paths:
|
153
118
|
- lib
|
154
119
|
required_ruby_version: !ruby/object:Gem::Requirement
|
155
|
-
none: false
|
156
120
|
requirements:
|
157
|
-
- -
|
121
|
+
- - ">="
|
158
122
|
- !ruby/object:Gem::Version
|
159
123
|
version: '0'
|
160
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
125
|
requirements:
|
163
|
-
- -
|
126
|
+
- - ">="
|
164
127
|
- !ruby/object:Gem::Version
|
165
128
|
version: '0'
|
166
129
|
requirements: []
|
167
130
|
rubyforge_project:
|
168
|
-
rubygems_version:
|
131
|
+
rubygems_version: 2.2.0
|
169
132
|
signing_key:
|
170
|
-
specification_version:
|
133
|
+
specification_version: 4
|
171
134
|
summary: A Resque plugin adding locking, with optional timeout/deadlock handling to
|
172
135
|
resque jobs.
|
173
136
|
test_files: []
|