resque-lonely_job 0.0.2 → 0.0.3
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.
- data/README.md +17 -4
- data/lib/resque-lonely_job/version.rb +1 -1
- data/lib/resque-lonely_job.rb +4 -4
- data/resque-lonely_job.gemspec +2 -1
- data/spec/lib/lonely_job_spec.rb +12 -8
- metadata +22 -11
data/README.md
CHANGED
|
@@ -8,8 +8,11 @@ time.
|
|
|
8
8
|
This differs from [resque-lock](from https://github.com/defunkt/resque-lock) and
|
|
9
9
|
[resque-loner](http://github.com/jayniz/resque-loner) in that the same job may
|
|
10
10
|
be queued multiple times but you're guaranteed that first job queued will run to
|
|
11
|
-
completion before subsequent jobs are run.
|
|
12
|
-
|
|
11
|
+
completion before subsequent jobs are run.
|
|
12
|
+
|
|
13
|
+
However, it is possible that subsequent jobs are re-ordered depending upon
|
|
14
|
+
worker behavior. Therefore it is recommended that the payload for jobs be
|
|
15
|
+
stored in a separate redis list distinct from the Resque queue (see Example #3).
|
|
13
16
|
|
|
14
17
|
## Installation
|
|
15
18
|
|
|
@@ -27,7 +30,7 @@ Or install it yourself as:
|
|
|
27
30
|
|
|
28
31
|
## Usage
|
|
29
32
|
|
|
30
|
-
#### Example #1
|
|
33
|
+
#### Example #1 -- One job running per queue
|
|
31
34
|
|
|
32
35
|
require 'resque/plugins/lonely_job'
|
|
33
36
|
|
|
@@ -42,7 +45,7 @@ Or install it yourself as:
|
|
|
42
45
|
end
|
|
43
46
|
end
|
|
44
47
|
|
|
45
|
-
#### Example #2
|
|
48
|
+
#### Example #2 -- One job running per user-defined attribute
|
|
46
49
|
|
|
47
50
|
Let's say you want the serial constraint to apply at a more granular
|
|
48
51
|
level. Instead of applying at the queue level, you can overwrite the .redis\_key
|
|
@@ -62,6 +65,12 @@ method.
|
|
|
62
65
|
"lonely_job:strictly_serial_job:#{account_id}"
|
|
63
66
|
end
|
|
64
67
|
|
|
68
|
+
# Overwrite reenqueue to lpush instead of default rpush. This attempts to
|
|
69
|
+
# preserve job ordering but job order is *NOT* guaranteed.
|
|
70
|
+
def self.reenqueue(*args)
|
|
71
|
+
Resque.redis.lpush("queue:#{Resque.queue_from_class(self)}", Resque.encode(class: self, args: args))
|
|
72
|
+
end
|
|
73
|
+
|
|
65
74
|
def self.perform(account_id, *args)
|
|
66
75
|
# only one at a time in this block, no parallelism allowed for this
|
|
67
76
|
# particular redis_key
|
|
@@ -98,6 +107,10 @@ where you have three jobs in the queue with two resque workers:
|
|
|
98
107
|
http://blog.kabisa.nl/2010/03/16/dynamic-queue-assignment-for-resque-jobs/,
|
|
99
108
|
where the queue is a one to one mapping to the redis\_key.
|
|
100
109
|
|
|
110
|
+
#### Example #3 -- One job running per user-defined attribute with job ordering preserved
|
|
111
|
+
|
|
112
|
+
TODO
|
|
113
|
+
|
|
101
114
|
## Contributing
|
|
102
115
|
|
|
103
116
|
1. Fork it
|
data/lib/resque-lonely_job.rb
CHANGED
|
@@ -27,14 +27,14 @@ module Resque
|
|
|
27
27
|
# role our own. This is based on Resque.push but we don't need to
|
|
28
28
|
# call Resque.watch_queue as the queue should already exist if we're
|
|
29
29
|
# unable to get the lock.
|
|
30
|
-
def
|
|
31
|
-
Resque.
|
|
30
|
+
def reenqueue(*args)
|
|
31
|
+
Resque.enqueue(self, *args)
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def before_perform(*args)
|
|
35
35
|
unless can_lock_queue?(*args)
|
|
36
|
-
# can't get the lock, so
|
|
37
|
-
|
|
36
|
+
# can't get the lock, so re-enqueue the task
|
|
37
|
+
reenqueue(*args)
|
|
38
38
|
|
|
39
39
|
# and don't perform
|
|
40
40
|
raise Resque::Job::DontPerform
|
data/resque-lonely_job.gemspec
CHANGED
|
@@ -15,9 +15,10 @@ Gem::Specification.new do |gem|
|
|
|
15
15
|
gem.version = Resque::Plugins::LonelyJob::VERSION
|
|
16
16
|
|
|
17
17
|
gem.add_dependency 'resque', '~> 1.20.0'
|
|
18
|
-
gem.
|
|
18
|
+
gem.add_development_dependency 'mock_redis', '~> 0.4.1'
|
|
19
19
|
gem.add_development_dependency 'rake'
|
|
20
20
|
gem.add_development_dependency 'rspec'
|
|
21
|
+
gem.add_development_dependency 'debugger'
|
|
21
22
|
|
|
22
23
|
gem.description = <<desc
|
|
23
24
|
Ensures that for a given queue, only one worker is working on a job at any given time.
|
data/spec/lib/lonely_job_spec.rb
CHANGED
|
@@ -65,9 +65,11 @@ describe Resque::Plugins::LonelyJob do
|
|
|
65
65
|
-> { job.perform }.should raise_error(Exception)
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
it 'should place self at the
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
it 'should place self at the end of the queue if unable to acquire the lock' do
|
|
69
|
+
job1_payload = %w[account_one job_one]
|
|
70
|
+
job2_payload = %w[account_one job_two]
|
|
71
|
+
Resque::Job.create(:serial_work, 'SerialJob', job1_payload)
|
|
72
|
+
Resque::Job.create(:serial_work, 'SerialJob', job2_payload)
|
|
71
73
|
|
|
72
74
|
SerialJob.should_receive(:can_lock_queue?).and_return(false)
|
|
73
75
|
|
|
@@ -77,7 +79,7 @@ describe Resque::Plugins::LonelyJob do
|
|
|
77
79
|
job1.perform.should be_false
|
|
78
80
|
|
|
79
81
|
first_queue_element = Resque.reserve(:serial_work)
|
|
80
|
-
first_queue_element.should ==
|
|
82
|
+
first_queue_element.payload["args"].should == [job2_payload]
|
|
81
83
|
end
|
|
82
84
|
end
|
|
83
85
|
|
|
@@ -111,9 +113,11 @@ describe Resque::Plugins::LonelyJob do
|
|
|
111
113
|
-> { job.perform }.should raise_error(Exception)
|
|
112
114
|
end
|
|
113
115
|
|
|
114
|
-
it 'should place self at the
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
it 'should place self at the end of the queue if unable to acquire the lock' do
|
|
117
|
+
job1_payload = %w[account_one job_one]
|
|
118
|
+
job2_payload = %w[account_one job_two]
|
|
119
|
+
Resque::Job.create(:serial_work, 'SerialJobWithCustomRedisKey', job1_payload)
|
|
120
|
+
Resque::Job.create(:serial_work, 'SerialJobWithCustomRedisKey', job2_payload)
|
|
117
121
|
|
|
118
122
|
SerialJobWithCustomRedisKey.should_receive(:can_lock_queue?).and_return(false)
|
|
119
123
|
|
|
@@ -123,7 +127,7 @@ describe Resque::Plugins::LonelyJob do
|
|
|
123
127
|
job1.perform.should be_false
|
|
124
128
|
|
|
125
129
|
first_queue_element = Resque.reserve(:serial_work)
|
|
126
|
-
first_queue_element.should ==
|
|
130
|
+
first_queue_element.payload["args"].should == [job2_payload]
|
|
127
131
|
end
|
|
128
132
|
end
|
|
129
133
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: resque-lonely_job
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.3
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,11 +9,11 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-
|
|
12
|
+
date: 2012-06-14 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: resque
|
|
16
|
-
requirement: &
|
|
16
|
+
requirement: &70264194773380 !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ~>
|
|
@@ -21,21 +21,21 @@ dependencies:
|
|
|
21
21
|
version: 1.20.0
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements: *
|
|
24
|
+
version_requirements: *70264194773380
|
|
25
25
|
- !ruby/object:Gem::Dependency
|
|
26
26
|
name: mock_redis
|
|
27
|
-
requirement: &
|
|
27
|
+
requirement: &70264194772640 !ruby/object:Gem::Requirement
|
|
28
28
|
none: false
|
|
29
29
|
requirements:
|
|
30
30
|
- - ~>
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: 0.4.1
|
|
33
|
-
type: :
|
|
33
|
+
type: :development
|
|
34
34
|
prerelease: false
|
|
35
|
-
version_requirements: *
|
|
35
|
+
version_requirements: *70264194772640
|
|
36
36
|
- !ruby/object:Gem::Dependency
|
|
37
37
|
name: rake
|
|
38
|
-
requirement: &
|
|
38
|
+
requirement: &70264194772020 !ruby/object:Gem::Requirement
|
|
39
39
|
none: false
|
|
40
40
|
requirements:
|
|
41
41
|
- - ! '>='
|
|
@@ -43,10 +43,21 @@ dependencies:
|
|
|
43
43
|
version: '0'
|
|
44
44
|
type: :development
|
|
45
45
|
prerelease: false
|
|
46
|
-
version_requirements: *
|
|
46
|
+
version_requirements: *70264194772020
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
48
|
name: rspec
|
|
49
|
-
requirement: &
|
|
49
|
+
requirement: &70264194771040 !ruby/object:Gem::Requirement
|
|
50
|
+
none: false
|
|
51
|
+
requirements:
|
|
52
|
+
- - ! '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
type: :development
|
|
56
|
+
prerelease: false
|
|
57
|
+
version_requirements: *70264194771040
|
|
58
|
+
- !ruby/object:Gem::Dependency
|
|
59
|
+
name: debugger
|
|
60
|
+
requirement: &70264194768800 !ruby/object:Gem::Requirement
|
|
50
61
|
none: false
|
|
51
62
|
requirements:
|
|
52
63
|
- - ! '>='
|
|
@@ -54,7 +65,7 @@ dependencies:
|
|
|
54
65
|
version: '0'
|
|
55
66
|
type: :development
|
|
56
67
|
prerelease: false
|
|
57
|
-
version_requirements: *
|
|
68
|
+
version_requirements: *70264194768800
|
|
58
69
|
description: ! "Ensures that for a given queue, only one worker is working on a job
|
|
59
70
|
at any given time.\n\nExample:\n\n require 'resque/plugins/lonely_job'\n\n class
|
|
60
71
|
StrictlySerialJob\n extend Resque::Plugins::LonelyJob\n\n @queue = :serial_work\n\n
|