resque-concurrent-restriction 0.5.4 → 0.5.5
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/.travis.yml +10 -0
- data/lib/resque/plugins/concurrent_restriction/concurrent_restriction_job.rb +9 -5
- data/lib/resque/plugins/concurrent_restriction/version.rb +1 -1
- data/resque-concurrent-restriction.gemspec +5 -0
- data/spec/concurrent_restriction_job_spec.rb +13 -6
- data/spec/redis-test.conf +1 -1
- data/spec/resque_worker_extensions_spec.rb +46 -9
- data/spec/spec_helper.rb +35 -16
- metadata +58 -11
data/.travis.yml
ADDED
@@ -130,7 +130,7 @@ module Resque
|
|
130
130
|
"concurrent.runnable#{key}"
|
131
131
|
end
|
132
132
|
|
133
|
-
# Encodes the job
|
133
|
+
# Encodes the job into the restriction queue
|
134
134
|
def encode(job)
|
135
135
|
item = {:queue => job.queue, :payload => job.payload}
|
136
136
|
Resque.encode(item)
|
@@ -189,7 +189,6 @@ module Resque
|
|
189
189
|
decrement_queue_count(queue)
|
190
190
|
|
191
191
|
# increment by one to indicate that we are running
|
192
|
-
# do this before update_queues_available so that the current queue gets cleaned
|
193
192
|
increment_running_count(tracking_key) if str
|
194
193
|
|
195
194
|
decode(str)
|
@@ -226,10 +225,15 @@ module Resque
|
|
226
225
|
return restricted
|
227
226
|
end
|
228
227
|
|
228
|
+
# The value in redis is the number of jobs currently running
|
229
|
+
# If we increment past that, we are restricted. Incrementing is only done
|
230
|
+
# after the job is cleared for execution due to checking the runnable
|
231
|
+
# state, and post increment we setup runnable for future jobs based on
|
232
|
+
# the new "restricted" value
|
229
233
|
def increment_running_count(tracking_key)
|
230
234
|
count_key = running_count_key(tracking_key)
|
231
235
|
value = Resque.redis.incr(count_key)
|
232
|
-
restricted = (value
|
236
|
+
restricted = (value >= concurrent_limit)
|
233
237
|
mark_runnable(tracking_key, !restricted)
|
234
238
|
return restricted
|
235
239
|
end
|
@@ -351,7 +355,7 @@ module Resque
|
|
351
355
|
end
|
352
356
|
trying = false
|
353
357
|
else
|
354
|
-
sleep
|
358
|
+
sleep(rand(1000) * 0.0001 * exp_backoff)
|
355
359
|
exp_backoff *= 2
|
356
360
|
end
|
357
361
|
end
|
@@ -391,7 +395,7 @@ module Resque
|
|
391
395
|
lock_key = lock_key(tracking_key)
|
392
396
|
|
393
397
|
run_atomically(lock_key) do
|
394
|
-
|
398
|
+
|
395
399
|
# since we don't have a lock when we get the runnable,
|
396
400
|
# we need to check it again
|
397
401
|
still_runnable = runnable?(tracking_key, queue)
|
@@ -21,7 +21,12 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.require_paths = ["lib"]
|
22
22
|
|
23
23
|
s.add_dependency("resque", '~> 1.10')
|
24
|
+
|
25
|
+
s.add_development_dependency('json')
|
24
26
|
s.add_development_dependency('rspec', '~> 2.5')
|
25
27
|
s.add_development_dependency('awesome_print')
|
26
28
|
|
29
|
+
# Needed for testing newer resque on ruby 1.8.7
|
30
|
+
s.add_development_dependency('json')
|
31
|
+
|
27
32
|
end
|
@@ -61,7 +61,7 @@ describe Resque::Plugins::ConcurrentRestriction do
|
|
61
61
|
|
62
62
|
it "should encode jobs correctly" do
|
63
63
|
job = Resque::Job.new("somequeue", {"class" => "RestrictionJob", "args" => [1, 2, 3]})
|
64
|
-
ConcurrentRestrictionJob.encode(job).should == '{"queue":"somequeue","payload":{"class":"RestrictionJob","args":[1,2,3]}}'
|
64
|
+
JSON.parse(ConcurrentRestrictionJob.encode(job)).should == JSON.parse('{"queue":"somequeue","payload":{"class":"RestrictionJob","args":[1,2,3]}}')
|
65
65
|
end
|
66
66
|
|
67
67
|
it "should decode jobs correctly" do
|
@@ -177,23 +177,30 @@ describe Resque::Plugins::ConcurrentRestriction do
|
|
177
177
|
end
|
178
178
|
|
179
179
|
it "should increment running count" do
|
180
|
-
ConcurrentRestrictionJob.stub!(:concurrent_limit).and_return(
|
180
|
+
ConcurrentRestrictionJob.stub!(:concurrent_limit).and_return(2)
|
181
181
|
ConcurrentRestrictionJob.running_count(ConcurrentRestrictionJob.tracking_key).should == 0
|
182
182
|
ConcurrentRestrictionJob.increment_running_count(ConcurrentRestrictionJob.tracking_key).should == false
|
183
183
|
ConcurrentRestrictionJob.running_count(ConcurrentRestrictionJob.tracking_key).should == 1
|
184
184
|
ConcurrentRestrictionJob.increment_running_count(ConcurrentRestrictionJob.tracking_key).should == true
|
185
185
|
ConcurrentRestrictionJob.running_count(ConcurrentRestrictionJob.tracking_key).should == 2
|
186
|
+
ConcurrentRestrictionJob.increment_running_count(ConcurrentRestrictionJob.tracking_key).should == true
|
187
|
+
ConcurrentRestrictionJob.running_count(ConcurrentRestrictionJob.tracking_key).should == 3
|
186
188
|
end
|
187
189
|
|
188
190
|
it "should decrement running count" do
|
189
|
-
ConcurrentRestrictionJob.stub!(:concurrent_limit).and_return(
|
190
|
-
ConcurrentRestrictionJob.set_running_count(ConcurrentRestrictionJob.tracking_key,
|
191
|
+
ConcurrentRestrictionJob.stub!(:concurrent_limit).and_return(2)
|
192
|
+
ConcurrentRestrictionJob.set_running_count(ConcurrentRestrictionJob.tracking_key, 3)
|
191
193
|
ConcurrentRestrictionJob.decrement_running_count(ConcurrentRestrictionJob.tracking_key).should == true
|
192
|
-
ConcurrentRestrictionJob.running_count(ConcurrentRestrictionJob.tracking_key).should ==
|
194
|
+
ConcurrentRestrictionJob.running_count(ConcurrentRestrictionJob.tracking_key).should == 2
|
193
195
|
ConcurrentRestrictionJob.decrement_running_count(ConcurrentRestrictionJob.tracking_key).should == false
|
194
|
-
ConcurrentRestrictionJob.running_count(ConcurrentRestrictionJob.tracking_key).should ==
|
196
|
+
ConcurrentRestrictionJob.running_count(ConcurrentRestrictionJob.tracking_key).should == 1
|
195
197
|
ConcurrentRestrictionJob.decrement_running_count(ConcurrentRestrictionJob.tracking_key).should == false
|
196
198
|
ConcurrentRestrictionJob.running_count(ConcurrentRestrictionJob.tracking_key).should == 0
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should not decrement running count below 0" do
|
202
|
+
ConcurrentRestrictionJob.stub!(:concurrent_limit).and_return(1)
|
203
|
+
ConcurrentRestrictionJob.set_running_count(ConcurrentRestrictionJob.tracking_key, 0)
|
197
204
|
ConcurrentRestrictionJob.decrement_running_count(ConcurrentRestrictionJob.tracking_key).should == false
|
198
205
|
ConcurrentRestrictionJob.running_count(ConcurrentRestrictionJob.tracking_key).should == 0
|
199
206
|
end
|
data/spec/redis-test.conf
CHANGED
@@ -21,7 +21,7 @@ daemonize yes
|
|
21
21
|
pidfile ./redis.pid
|
22
22
|
|
23
23
|
# Accept connections on the specified port, default is 6379
|
24
|
-
port
|
24
|
+
port 6379
|
25
25
|
|
26
26
|
# If you want you can bind a single interface, if the bind option is not
|
27
27
|
# specified all the interfaces will listen for incoming connections.
|
@@ -143,41 +143,78 @@ describe Resque::Plugins::ConcurrentRestriction::Worker do
|
|
143
143
|
|
144
144
|
it "should run multiple jobs concurrently" do
|
145
145
|
7.times {|i| Resque.enqueue(MultipleConcurrentRestrictionJob, i) }
|
146
|
-
|
146
|
+
|
147
147
|
7.times do
|
148
148
|
unless child = fork
|
149
|
-
Resque.redis
|
149
|
+
Resque.redis.client.connect
|
150
150
|
run_resque_queue('*')
|
151
151
|
exit!
|
152
152
|
end
|
153
153
|
end
|
154
154
|
sleep 0.25
|
155
|
-
|
155
|
+
|
156
156
|
MultipleConcurrentRestrictionJob.total_run_count.should == 4
|
157
157
|
MultipleConcurrentRestrictionJob.running_count(MultipleConcurrentRestrictionJob.tracking_key).should == 4
|
158
158
|
MultipleConcurrentRestrictionJob.restriction_queue(MultipleConcurrentRestrictionJob.tracking_key, :normal).size.should == 3
|
159
|
-
|
159
|
+
|
160
160
|
Process.waitall
|
161
|
-
|
161
|
+
|
162
162
|
3.times do
|
163
163
|
unless child = fork
|
164
|
-
Resque.redis
|
164
|
+
Resque.redis.client.connect
|
165
165
|
run_resque_queue('*')
|
166
166
|
exit!
|
167
167
|
end
|
168
168
|
end
|
169
169
|
sleep 0.25
|
170
|
-
|
170
|
+
|
171
171
|
MultipleConcurrentRestrictionJob.total_run_count.should == 7
|
172
172
|
MultipleConcurrentRestrictionJob.running_count(MultipleConcurrentRestrictionJob.tracking_key).should == 3
|
173
173
|
MultipleConcurrentRestrictionJob.restriction_queue(MultipleConcurrentRestrictionJob.tracking_key, :normal).size.should == 0
|
174
|
-
|
174
|
+
|
175
175
|
Process.waitall
|
176
|
-
|
176
|
+
|
177
177
|
MultipleConcurrentRestrictionJob.running_count(MultipleConcurrentRestrictionJob.tracking_key).should == 0
|
178
178
|
MultipleConcurrentRestrictionJob.total_run_count.should == 7
|
179
179
|
end
|
180
180
|
|
181
|
+
it "should run only one concurrent job" do
|
182
|
+
5.times {|i| Resque.enqueue(OneConcurrentRestrictionJob, i) }
|
183
|
+
5.times do
|
184
|
+
unless child = fork
|
185
|
+
Resque.redis.client.connect
|
186
|
+
run_resque_queue('*')
|
187
|
+
exit!
|
188
|
+
end
|
189
|
+
end
|
190
|
+
sleep 0.25
|
191
|
+
|
192
|
+
OneConcurrentRestrictionJob.total_run_count.should == 1
|
193
|
+
OneConcurrentRestrictionJob.running_count(OneConcurrentRestrictionJob.tracking_key).should == 1
|
194
|
+
OneConcurrentRestrictionJob.restriction_queue(OneConcurrentRestrictionJob.tracking_key, :normal).size.should == 4
|
195
|
+
|
196
|
+
Process.waitall
|
197
|
+
|
198
|
+
2.times do
|
199
|
+
unless child = fork
|
200
|
+
Resque.redis.client.connect
|
201
|
+
run_resque_queue('*')
|
202
|
+
exit!
|
203
|
+
end
|
204
|
+
end
|
205
|
+
sleep 0.25
|
206
|
+
|
207
|
+
OneConcurrentRestrictionJob.total_run_count.should == 2
|
208
|
+
OneConcurrentRestrictionJob.running_count(OneConcurrentRestrictionJob.tracking_key).should == 1
|
209
|
+
OneConcurrentRestrictionJob.restriction_queue(OneConcurrentRestrictionJob.tracking_key, :normal).size.should == 3
|
210
|
+
|
211
|
+
Process.waitall
|
212
|
+
|
213
|
+
OneConcurrentRestrictionJob.running_count(OneConcurrentRestrictionJob.tracking_key).should == 0
|
214
|
+
OneConcurrentRestrictionJob.total_run_count.should == 2
|
215
|
+
|
216
|
+
end
|
217
|
+
|
181
218
|
it "should decrement execution number when concurrent job fails" do
|
182
219
|
run_resque_job(ConcurrentRestrictionJob, "bad")
|
183
220
|
Resque.redis.lrange("failed", 0, -1).size.should == 1
|
data/spec/spec_helper.rb
CHANGED
@@ -1,26 +1,33 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
require 'ap'
|
3
3
|
|
4
|
-
spec_dir = File.dirname(File.expand_path(__FILE__))
|
5
|
-
REDIS_CMD = "redis-server #{spec_dir}/redis-test.conf"
|
6
|
-
|
7
|
-
puts "Starting redis for testing at localhost:9736..."
|
8
|
-
puts `cd #{spec_dir}; #{REDIS_CMD}`
|
9
|
-
|
10
|
-
require 'resque'
|
11
|
-
Resque.redis = 'localhost:9736'
|
12
4
|
require 'resque-concurrent-restriction'
|
13
5
|
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
6
|
+
# No need to start redis when running in Travis
|
7
|
+
unless ENV['CI']
|
8
|
+
|
9
|
+
begin
|
10
|
+
Resque.queues
|
11
|
+
rescue Errno::ECONNREFUSED
|
12
|
+
spec_dir = File.dirname(File.expand_path(__FILE__))
|
13
|
+
REDIS_CMD = "redis-server #{spec_dir}/redis-test.conf"
|
14
|
+
|
15
|
+
puts "Starting redis for testing at localhost..."
|
16
|
+
puts `cd #{spec_dir}; #{REDIS_CMD}`
|
17
|
+
|
18
|
+
# Schedule the redis server for shutdown when tests are all finished.
|
19
|
+
at_exit do
|
20
|
+
puts 'Stopping redis'
|
21
|
+
pid = File.read("#{spec_dir}/redis.pid").to_i rescue nil
|
22
|
+
system ("kill -9 #{pid}") if pid.to_i != 0
|
23
|
+
File.delete("#{spec_dir}/redis.pid") rescue nil
|
24
|
+
File.delete("#{spec_dir}/redis-server.log") rescue nil
|
25
|
+
File.delete("#{spec_dir}/dump.rdb") rescue nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
21
29
|
end
|
22
30
|
|
23
|
-
|
24
31
|
##
|
25
32
|
# Helper to perform job classes
|
26
33
|
#
|
@@ -160,3 +167,15 @@ class MultipleConcurrentRestrictionJob
|
|
160
167
|
sleep 0.5
|
161
168
|
end
|
162
169
|
end
|
170
|
+
|
171
|
+
class OneConcurrentRestrictionJob
|
172
|
+
extend RunCountHelper
|
173
|
+
extend Resque::Plugins::ConcurrentRestriction
|
174
|
+
concurrent 1
|
175
|
+
|
176
|
+
@queue = 'normal'
|
177
|
+
|
178
|
+
def self.perform(*args)
|
179
|
+
sleep 0.5
|
180
|
+
end
|
181
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-concurrent-restriction
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,12 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
default_executable:
|
12
|
+
date: 2012-04-23 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: resque
|
17
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
18
17
|
none: false
|
19
18
|
requirements:
|
20
19
|
- - ~>
|
@@ -22,10 +21,31 @@ dependencies:
|
|
22
21
|
version: '1.10'
|
23
22
|
type: :runtime
|
24
23
|
prerelease: false
|
25
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.10'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
26
46
|
- !ruby/object:Gem::Dependency
|
27
47
|
name: rspec
|
28
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
29
49
|
none: false
|
30
50
|
requirements:
|
31
51
|
- - ~>
|
@@ -33,10 +53,31 @@ dependencies:
|
|
33
53
|
version: '2.5'
|
34
54
|
type: :development
|
35
55
|
prerelease: false
|
36
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.5'
|
37
62
|
- !ruby/object:Gem::Dependency
|
38
63
|
name: awesome_print
|
39
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: json
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
40
81
|
none: false
|
41
82
|
requirements:
|
42
83
|
- - ! '>='
|
@@ -44,7 +85,12 @@ dependencies:
|
|
44
85
|
version: '0'
|
45
86
|
type: :development
|
46
87
|
prerelease: false
|
47
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
48
94
|
description: A resque plugin for limiting how many of a specific job can run concurrently
|
49
95
|
email:
|
50
96
|
- matt@conwaysplace.com
|
@@ -53,6 +99,7 @@ extensions: []
|
|
53
99
|
extra_rdoc_files: []
|
54
100
|
files:
|
55
101
|
- .gitignore
|
102
|
+
- .travis.yml
|
56
103
|
- Gemfile
|
57
104
|
- LICENSE
|
58
105
|
- README.md
|
@@ -67,7 +114,6 @@ files:
|
|
67
114
|
- spec/resque_worker_extensions_spec.rb
|
68
115
|
- spec/spec.opts
|
69
116
|
- spec/spec_helper.rb
|
70
|
-
has_rdoc: true
|
71
117
|
homepage: http://github.com/wr0ngway/resque-concurrent-restriction
|
72
118
|
licenses: []
|
73
119
|
post_install_message:
|
@@ -88,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
134
|
version: '0'
|
89
135
|
requirements: []
|
90
136
|
rubyforge_project: resque-concurrent-restriction
|
91
|
-
rubygems_version: 1.
|
137
|
+
rubygems_version: 1.8.21
|
92
138
|
signing_key:
|
93
139
|
specification_version: 3
|
94
140
|
summary: A resque plugin for limiting how many of a specific job can run concurrently
|
@@ -98,3 +144,4 @@ test_files:
|
|
98
144
|
- spec/resque_worker_extensions_spec.rb
|
99
145
|
- spec/spec.opts
|
100
146
|
- spec/spec_helper.rb
|
147
|
+
has_rdoc:
|