resque-director 2.2.2 → 2.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY.md ADDED
@@ -0,0 +1,41 @@
1
+ ## 2.2.2 (2011-09-09)
2
+
3
+ * Bugfix: ignore wait_time when scaling to be within limits
4
+
5
+ ## 2.2.1 (2011-09-07)
6
+
7
+ * Bugfix: make compatible with ruby 1.9
8
+
9
+ ## 2.2.0 (2011-09-07)
10
+
11
+ * Added scaling workers working on multiple queues
12
+
13
+ ## 2.1.1 (2011-09-02)
14
+
15
+ * Dont update last scaled time if start/stop block returns false
16
+
17
+ ## 2.1.0 (2011-09-01)
18
+
19
+ * Change default log level to debug
20
+ * Make gem compatible with resque ~> 1.10
21
+ * add `no_enqueue_scale` option
22
+ * scale within requirements before perform
23
+
24
+ ## 2.0.0 (2011-08-24)
25
+
26
+ * Must extend the plugin instead of include
27
+ * Modify resque's push/pop functionality to track time
28
+ * Start/stop override lambdas accept queue-name as an argument
29
+
30
+ ## 1.1.0 (2011-08-23)
31
+
32
+ * Added logging options
33
+ * Bugfix: don't raise error when killing worker process
34
+
35
+ ## 1.0.1 (2011-08-20)
36
+
37
+ * Bugfix: Dont append timestamp argument to resque job for non directed jobs
38
+
39
+ ## 1.0.0 (2011-08-20)
40
+
41
+ * 1.0 release.
data/README.rdoc CHANGED
@@ -4,7 +4,7 @@ Resque Director is a plugin for the Resque queueing system (http://github.com/de
4
4
 
5
5
  ==About
6
6
 
7
- resque-director is mainly useful for when you are managing a large number of workers and don't want to waste resources keeping all of them waiting when they are not being used. Also for jobs that are high priority or time sensitive you can have it autoscale workers when the time it took for the job to go through the queue is too long. For this reason resque director is useful in queues where the influx of jobs can change dramatically from time to time: enabling more workers during the times when the queue is filling up more quickly, and less in the opposite scenario. Different queues can be given different directions as well.
7
+ Resque-director is useful for when you are managing a large number of workers and don't want to waste resources keeping all of them waiting when they are not being used. For jobs that are high priority or time sensitive you can have it autoscale workers based on how long it takes to go through the queue, or how big the queue becomes. In queues where the influx of jobs can change dramatically from time to time, resque director automatically scales more workers during the times when the queue is filling up more quickly, and less in the opposite scenario. Different queues can be given different directions as well.
8
8
 
9
9
  == Usage
10
10
 
@@ -27,7 +27,7 @@ For Example:
27
27
 
28
28
  <b>max_workers</b>:: specifies the maximum number of workers running at any point in time. It will never start more than the maximum number of workers. If anything less than or equal to zero is specified as the maximum it will be treated as if there is no maximum, and theoretically an infinite number of workers could be started. The default is 0.
29
29
 
30
- <b>max_time</b>:: the maximum time in seconds that a job takes to get pulled off the queue, if a job takes longer than this time then a worker is started. If anything less than or equal to zero is specified as the maximum time, this field will be ignored. The default is 0.
30
+ <b>max_time</b>:: the maximum time in seconds that a job takes to go through the queue, if it takes longer than this time then a worker is started. If anything less than or equal to zero is specified as the maximum time, this field will be ignored. The default is 0.
31
31
 
32
32
  <b>max_queue</b>:: the maximum jobs that can build up in a queue, if more than this number of jobs build up then a worker is started. If anything less than or equal to zero is specified as the maximum queue, this field will be ignored. The default is 0.
33
33
 
@@ -35,7 +35,7 @@ For Example:
35
35
 
36
36
  === Conditions For Starting Workers
37
37
 
38
- A worker will be started if the queue length is greater than <b>max_queue</b> or if the time it takes a job to go through the queue is greater than <b>max_time</b>. Also a worker will only be started if the time since the last scaling is greater than <b>wait_time</b>. Workers will not be started if there are already the <b>max_workers</b> number of workers. By default resque-director allows you to have zero jobs running, when a job is enqueued then workers will be scaled within the max/min requirements you set. If there is not a single worker running, then the minimum number of workers will be scaled up (one worker will be scaled up if the minimum is zero).
38
+ A worker will be started if the queue length is greater than <b>max_queue</b> or if the time it takes a job to go through the queue is greater than <b>max_time</b>. Also a worker will only be started if the time since the last scaling is greater than <b>wait_time</b>. Workers will not be started if there are already the <b>max_workers</b> number of workers. By default resque-director allows you to have zero workers running, when a job is enqueued then workers will be scaled within the max/min requirements you set. If there is not a single worker running, then the minimum number of workers will be scaled up (one worker will be scaled up if the minimum is zero).
39
39
 
40
40
  === Conditions For Removing Workers
41
41
 
@@ -52,7 +52,7 @@ The above options are plenty to handle the basic scaling of workers. The options
52
52
 
53
53
  === Start/Stop Options
54
54
 
55
- <b>start_override</b>:: You can set this option if you want to override the way to start a worker. This option takes a lambda closure that accepts the queue as an argument, the block you pass in will be responsible for starting a <em>SINGLE</em> worker allowing you to fully customize the starting of a worker. If your block returns false then that signifies that a worker was not started and the last scaled time will not be set. The default way a worker is started is with the system command: <tt>QUEUE=queue_name rake resque:work &</tt> where "queue_name" is the queue on which the job is running.
55
+ <b>start_override</b>:: You can set this option if you want to override the way to start a worker. This option takes a lambda closure that accepts the queue as an argument, the block you pass in will be responsible for starting a <em>SINGLE</em> worker allowing you to fully customize the starting of a worker. If your block returns false then that signifies that a worker was not started and the last scaled time will not be set. The default way a worker is started is with the system command: "<tt>QUEUE=queue_name rake resque:work &</tt>" where "queue_name" is the queue on which the job is running.
56
56
 
57
57
  <b>stop_override</b>:: You can set this option if you want to override the way to stop a worker. This option takes a lambda closure that accepts the queue as an argument, the block you pass in will be responsible for stopping a <em>SINGLE</em> worker allowing you to fully customize the stopping of a worker. If your block returns false then that signifies that a worker was not stopped and the last scaled time will not be set. The default way a worker is stopped is that a QUIT signal is sent to a worker process.
58
58
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.2
1
+ 2.2.3
@@ -5,33 +5,30 @@ module Resque
5
5
  class << self
6
6
 
7
7
  def scale_up(number_of_workers=1)
8
- number_of_workers = WorkerTracker.new.total_to_add(number_of_workers)
8
+ number_of_workers = WorkerTracker.total_to_add(number_of_workers)
9
9
  scaling(number_of_workers) do
10
10
  start(number_of_workers)
11
11
  end
12
12
  end
13
13
 
14
14
  def scale_down(number_of_workers=1)
15
- tracker = WorkerTracker.new
16
- number_of_workers = tracker.total_to_remove(number_of_workers)
15
+ number_of_workers = WorkerTracker.total_to_remove(number_of_workers)
17
16
  scaling(number_of_workers) do
18
- stop(tracker, number_of_workers)
17
+ stop(number_of_workers)
19
18
  end
20
19
  end
21
20
 
22
21
  def scale_down_to_minimum
23
- tracker = WorkerTracker.new
24
- number_of_workers = tracker.total_to_go_to_minimum
25
- stop(tracker, number_of_workers)
22
+ number_of_workers = WorkerTracker.total_to_go_to_minimum
23
+ stop(number_of_workers)
26
24
  end
27
25
 
28
26
  def scale_within_requirements
29
- tracker = WorkerTracker.new
30
- number_of_workers = tracker.total_for_requirements
27
+ number_of_workers = WorkerTracker.total_for_requirements
31
28
  if number_of_workers > 0
32
29
  set_last_scaled unless start(number_of_workers) == false
33
30
  elsif number_of_workers < 0
34
- set_last_scaled unless stop(tracker, number_of_workers * -1) == false
31
+ set_last_scaled unless stop(number_of_workers * -1) == false
35
32
  end
36
33
  end
37
34
 
@@ -59,10 +56,10 @@ module Resque
59
56
  start_default(number_of_workers)
60
57
  end
61
58
 
62
- def stop(tracker, number_of_workers)
59
+ def stop(number_of_workers)
63
60
  Config.log("stopping #{number_of_workers} workers on queue:#{Config.queue}") if number_of_workers > 0
64
61
  return override(number_of_workers, Config.stop_override) if Config.stop_override
65
- stop_default(tracker, number_of_workers)
62
+ stop_default(number_of_workers)
66
63
  end
67
64
 
68
65
  def override(number_of_workers, override_block)
@@ -73,8 +70,8 @@ module Resque
73
70
  number_of_workers.times { system("QUEUE=#{[Config.queue].flatten.join(",")} rake resque:work &") }
74
71
  end
75
72
 
76
- def stop_default(tracker, number_of_workers)
77
- worker_pids = tracker.valid_worker_pids[0...number_of_workers]
73
+ def stop_default(number_of_workers)
74
+ worker_pids = WorkerTracker.valid_worker_pids[0...number_of_workers]
78
75
  worker_pids.each do |pid|
79
76
  Process.kill("QUIT", pid) rescue nil
80
77
  end
@@ -2,62 +2,58 @@ module Resque
2
2
  module Plugins
3
3
  module Director
4
4
  class WorkerTracker
5
- attr_reader :workers
6
-
7
- def initialize
8
- @workers = current_workers
9
- @number_working = @workers.size
10
- end
5
+ class << self
11
6
 
12
- def total_for_requirements
13
- start_number = workers_to_start
14
- stop_number = workers_to_stop
15
- return start_number if start_number > 0
16
- return stop_number if stop_number < 0
17
- 0
18
- end
7
+ def total_for_requirements
8
+ start_number = workers_to_start
9
+ stop_number = workers_to_stop
10
+ return start_number if start_number > 0
11
+ return stop_number if stop_number < 0
12
+ 0
13
+ end
19
14
 
20
- def total_to_go_to_minimum
21
- to_minimum = @number_working - Config.min_workers
22
- to_minimum > 0 ? to_minimum : 0
23
- end
15
+ def total_to_go_to_minimum
16
+ to_minimum = current_workers.size - Config.min_workers
17
+ to_minimum > 0 ? to_minimum : 0
18
+ end
24
19
 
25
- def total_to_add(number_to_start)
26
- return number_to_start if Config.max_workers <= 0
27
- scale_limit = Config.max_workers - @number_working
28
- Config.log("WORKER MAX REACHED: wanted to start #{number_to_start} workers on queue:#{Config.queue}") if scale_limit <= 0
29
- number_to_start > scale_limit ? scale_limit : number_to_start
30
- end
20
+ def total_to_add(number_to_start)
21
+ return number_to_start if Config.max_workers <= 0
22
+ scale_limit = Config.max_workers - current_workers.size
23
+ Config.log("WORKER MAX REACHED: wanted to start #{number_to_start} workers on queue:#{Config.queue}") if scale_limit <= 0
24
+ number_to_start > scale_limit ? scale_limit : number_to_start
25
+ end
31
26
 
32
- def total_to_remove(number_to_stop)
33
- min_workers = Config.min_workers <= 0 ? 1 : Config.min_workers
34
- scale_limit = @number_working - min_workers
35
- if scale_limit <= 0 && Config.min_workers > 0
36
- Config.log("WORKER MIN REACHED: wanted to stop #{number_to_stop} workers on queue:#{Config.queue}")
27
+ def total_to_remove(number_to_stop)
28
+ min_workers = Config.min_workers <= 0 ? 1 : Config.min_workers
29
+ scale_limit = current_workers.size - min_workers
30
+ if scale_limit <= 0 && Config.min_workers > 0
31
+ Config.log("WORKER MIN REACHED: wanted to stop #{number_to_stop} workers on queue:#{Config.queue}")
32
+ end
33
+ number_to_stop > scale_limit ? scale_limit : number_to_stop
37
34
  end
38
- number_to_stop > scale_limit ? scale_limit : number_to_stop
39
- end
40
35
 
41
- def valid_worker_pids
42
- valid_workers = @workers.select{|w| w.hostname == `hostname`.chomp}
43
- valid_workers.map{|worker| worker.to_s.split(":")[1].to_i }
44
- end
36
+ def valid_worker_pids
37
+ valid_workers = current_workers.select{|w| w.hostname == `hostname`.chomp}
38
+ valid_workers.map{|worker| worker.to_s.split(":")[1].to_i }
39
+ end
45
40
 
46
- private
41
+ private
47
42
 
48
- def workers_to_start
49
- min_workers = Config.min_workers <= 0 ? 1 : Config.min_workers
50
- min_workers - @number_working
51
- end
43
+ def workers_to_start
44
+ min_workers = Config.min_workers <= 0 ? 1 : Config.min_workers
45
+ min_workers - current_workers.size
46
+ end
52
47
 
53
- def workers_to_stop
54
- return 0 if Config.max_workers <= 0
55
- Config.max_workers - @number_working
56
- end
48
+ def workers_to_stop
49
+ return 0 if Config.max_workers <= 0
50
+ Config.max_workers - current_workers.size
51
+ end
57
52
 
58
- def current_workers
59
- Resque.workers.select do |w|
60
- w.queues.map(&:to_s) == [Config.queue].flatten.map(&:to_s) && !w.shutdown?
53
+ def current_workers
54
+ Resque.workers.select do |w|
55
+ w.queues.map(&:to_s) == [Config.queue].flatten.map(&:to_s) && !w.shutdown?
56
+ end
61
57
  end
62
58
  end
63
59
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{resque-director}
8
- s.version = "2.2.2"
8
+ s.version = "2.2.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = [%q{Nolan Frausto}]
12
- s.date = %q{2011-09-09}
12
+ s.date = %q{2011-10-13}
13
13
  s.description = %q{resque plugin for automatically scaling workers based on the amount of time it takes a job to go through the queue and/or the length of the queue }
14
14
  s.email = %q{nrfrausto@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -17,8 +17,8 @@ Gem::Specification.new do |s|
17
17
  "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
- ".document",
21
20
  "Gemfile",
21
+ "HISTORY.md",
22
22
  "LICENSE.txt",
23
23
  "README.rdoc",
24
24
  "Rakefile",
@@ -42,7 +42,7 @@ Gem::Specification.new do |s|
42
42
  s.homepage = %q{http://github.com/frausto/resque-director}
43
43
  s.licenses = [%q{MIT}]
44
44
  s.require_paths = [%q{lib}]
45
- s.rubygems_version = %q{1.8.8}
45
+ s.rubygems_version = %q{1.8.6}
46
46
  s.summary = %q{A resque plugin for automatically scaling workers}
47
47
 
48
48
  if s.respond_to? :specification_version then
@@ -94,13 +94,13 @@ describe Resque::Plugins::Director::Scaler do
94
94
  end
95
95
 
96
96
  it "should scale workers down to the minimum" do
97
- Resque.should_receive(:workers).and_return [@worker, @worker, @worker]
97
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker, @worker, @worker]
98
98
  Process.should_receive(:kill).twice
99
99
  subject.scale_down_to_minimum
100
100
  end
101
101
 
102
102
  it "should not scale if the workers are already at the minimum" do
103
- Resque.should_receive(:workers).and_return [@worker]
103
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker]
104
104
  Process.should_not_receive(:kill)
105
105
  subject.scale_down_to_minimum
106
106
  end
@@ -108,7 +108,7 @@ describe Resque::Plugins::Director::Scaler do
108
108
  it "forces scaling by ignoring wait_time" do
109
109
  Resque::Plugins::Director::Config.setup(:wait_time => 60, :min_workers => 2)
110
110
  subject.scaling {}
111
- Resque.should_receive(:workers).and_return [@worker, @worker, @worker]
111
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker, @worker, @worker]
112
112
  Process.should_receive(:kill)
113
113
  subject.scale_down_to_minimum
114
114
  end
@@ -121,14 +121,14 @@ describe Resque::Plugins::Director::Scaler do
121
121
  end
122
122
 
123
123
  it "should scale down a single worker by default" do
124
- Resque.should_receive(:workers).and_return [@worker, @worker]
124
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker, @worker]
125
125
 
126
126
  Process.should_receive(:kill).once
127
127
  subject.scale_down
128
128
  end
129
129
 
130
130
  it "should scale down multiple workers" do
131
- Resque.should_receive(:workers).and_return [@worker, @worker, @worker]
131
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker, @worker, @worker]
132
132
  pid = @worker.to_s.split(":")[1].to_i
133
133
  Process.should_receive(:kill).with("QUIT", pid)
134
134
  subject.scale_down(2)
@@ -137,13 +137,13 @@ describe Resque::Plugins::Director::Scaler do
137
137
  it "should not scale down more than the minimum allowed workers" do
138
138
  Resque::Plugins::Director::Config.setup :min_workers => 1
139
139
 
140
- Resque.should_receive(:workers).and_return [@worker, @worker]
140
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker, @worker]
141
141
  Process.should_receive(:kill).once
142
142
  subject.scale_down(2)
143
143
  end
144
144
 
145
145
  it "should not throw exceptions when process throws exception" do
146
- Resque.should_receive(:workers).and_return [@worker, @worker]
146
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker, @worker]
147
147
  Process.should_receive(:kill).and_throw(:Exception)
148
148
  lambda { subject.scale_down }.should_not raise_error
149
149
  end
@@ -152,7 +152,7 @@ describe Resque::Plugins::Director::Scaler do
152
152
  worker2 = Resque::Worker.new(:not_test)
153
153
  @worker.stub(:to_s => "host:1:test")
154
154
  worker2.stub(:to_s => "host:2:test")
155
- Resque.should_receive(:workers).and_return [worker2, @worker, @worker, worker2]
155
+ Resque.should_receive(:workers).any_number_of_times.and_return [worker2, @worker, @worker, worker2]
156
156
 
157
157
  Process.should_not_receive(:kill).with("QUIT", 2)
158
158
  Process.should_receive(:kill).with("QUIT", 1)
@@ -168,51 +168,46 @@ describe Resque::Plugins::Director::Scaler do
168
168
  end
169
169
 
170
170
  it "should kill worker by sending the QUIT signal to the workers pid" do
171
- Resque.should_receive(:workers).and_return [@worker]
172
- tracker = Resque::Plugins::Director::WorkerTracker.new
171
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker]
173
172
 
174
173
  Process.should_receive(:kill).with("QUIT", @pid)
175
- subject.send(:stop, tracker, 1)
174
+ subject.send(:stop, 1)
176
175
  end
177
176
 
178
177
  it "should use the stop block to stop a worker if set" do
179
178
  test_block = lambda {|queue| }
180
179
  Resque::Plugins::Director::Config.setup :stop_override => test_block, :min_workers => 0
181
180
 
182
- Resque.should_receive(:workers).and_return [@worker]
183
- tracker = Resque::Plugins::Director::WorkerTracker.new
181
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker]
184
182
 
185
183
  test_block.should_receive(:call).with("test")
186
184
  Process.should_not_receive(:kill)
187
- subject.send(:stop, tracker, 1)
185
+ subject.send(:stop, 1)
188
186
  end
189
187
 
190
188
  it "does not stop workers already set to be shutdown" do
191
189
  @worker.should_receive(:shutdown?).and_return(true)
192
- Resque.should_receive(:workers).and_return [@worker]
193
- tracker = Resque::Plugins::Director::WorkerTracker.new
190
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker]
194
191
 
195
192
  Process.should_not_receive(:kill).with("QUIT", @pid)
196
- subject.send(:stop, tracker, 1)
193
+ subject.send(:stop, 1)
197
194
  end
198
195
 
199
196
  it "does not kill worker processes on different machines" do
200
197
  @worker.stub!(:hostname => "different_machine")
201
- Resque.should_receive(:workers).and_return [@worker]
202
- tracker = Resque::Plugins::Director::WorkerTracker.new
198
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker]
203
199
 
204
200
  Process.should_not_receive(:kill).with("QUIT", @pid)
205
- subject.send(:stop, tracker, 1)
201
+ subject.send(:stop, 1)
206
202
  end
207
203
 
208
204
  it "stops workers on the same host if possible" do
209
205
  worker2 = Resque::Worker.new(:test)
210
206
  worker2.stub!(:hostname => "different_machine")
211
- Resque.should_receive(:workers).and_return [worker2, @worker]
212
- tracker = Resque::Plugins::Director::WorkerTracker.new
207
+ Resque.should_receive(:workers).any_number_of_times.and_return [worker2, @worker]
213
208
 
214
209
  Process.should_receive(:kill).with("QUIT", @pid)
215
- subject.send(:stop, tracker, 1)
210
+ subject.send(:stop, 1)
216
211
  end
217
212
 
218
213
  it "ignores hostname if using custom stop script" do
@@ -220,12 +215,11 @@ describe Resque::Plugins::Director::Scaler do
220
215
  Resque::Plugins::Director::Config.setup :stop_override => test_block, :min_workers => 0
221
216
 
222
217
  @worker.stub!(:hostname => "different_machine")
223
- Resque.should_receive(:workers).and_return [@worker]
224
- tracker = Resque::Plugins::Director::WorkerTracker.new
218
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker]
225
219
 
226
220
  test_block.should_receive(:call).with("test")
227
221
  Process.should_not_receive(:kill)
228
- subject.send(:stop, tracker, 1)
222
+ subject.send(:stop, 1)
229
223
  end
230
224
  end
231
225
 
@@ -264,7 +258,7 @@ describe Resque::Plugins::Director::Scaler do
264
258
  Time.stub(:now => @now)
265
259
  Resque::Plugins::Director::Config.setup :max_workers => 1, :wait_time => 60
266
260
  workers = 2.times.map { Resque::Worker.new(:test) }
267
- Resque.should_receive(:workers).and_return(workers)
261
+ Resque.should_receive(:workers).any_number_of_times.and_return(workers)
268
262
  subject.should_receive(:stop)
269
263
 
270
264
  subject.scale_within_requirements
@@ -293,16 +287,16 @@ describe Resque::Plugins::Director::Scaler do
293
287
  it "should scale down the max number of workers if more than max" do
294
288
  Resque::Plugins::Director::Config.setup :max_workers => 1
295
289
  workers = 2.times.map { Resque::Worker.new(:test) }
296
- Resque.should_receive(:workers).and_return(workers)
290
+ Resque.should_receive(:workers).any_number_of_times.and_return(workers)
297
291
 
298
- subject.should_receive(:stop).with(anything, 1)
292
+ subject.should_receive(:stop).with(1)
299
293
  subject.scale_within_requirements
300
294
  end
301
295
 
302
296
  it "should not scale down if max_workers is zero" do
303
297
  Resque::Plugins::Director::Config.setup :max_workers => 0
304
298
  workers = 1.times.map { Resque::Worker.new(:test) }
305
- Resque.should_receive(:workers).and_return(workers)
299
+ Resque.should_receive(:workers).any_number_of_times.and_return(workers)
306
300
 
307
301
  subject.should_not_receive(:stop)
308
302
  subject.scale_within_requirements
@@ -8,22 +8,50 @@ describe Resque::Plugins::Director::WorkerTracker do
8
8
  @worker = Resque::Worker.new(:test)
9
9
  end
10
10
 
11
- describe "#workers" do
12
- before do
13
- Resque::Plugins::Director::Config.queue = "worker_test"
14
- end
15
-
11
+ describe "#current_workers" do
16
12
  it"should return the workers for the queue" do
13
+ Resque::Plugins::Director::Config.queue = "worker_test"
17
14
  Resque::Worker.new(:other).register_worker
18
15
  expected_worker = Resque::Worker.new(:worker_test)
19
16
  expected_worker.register_worker
20
17
 
21
- subject.new.workers.should == [expected_worker]
18
+ subject.send(:current_workers).should == [expected_worker]
22
19
  end
23
20
 
24
21
  it "should not return workers working on multiple queues" do
25
22
  Resque::Worker.new(:worker_test, :other).register_worker
26
- subject.new.workers.should be_empty
23
+ subject.send(:current_workers).should be_empty
24
+ end
25
+
26
+ it "sets the workers from the queue" do
27
+ Resque.should_receive(:workers).and_return [@worker, @worker, @worker]
28
+ subject.send(:current_workers).should == [@worker, @worker, @worker]
29
+ end
30
+
31
+ it "does not set workers from different queues" do
32
+ other_worker = Resque::Worker.new(:other)
33
+ Resque.should_receive(:workers).and_return [@worker, other_worker, @worker]
34
+ subject.send(:current_workers).should == [@worker, @worker]
35
+ end
36
+
37
+ it "does not set workers that are scheduled for shutdow" do
38
+ shutdown_worker = Resque::Worker.new(:test)
39
+ shutdown_worker.shutdown
40
+ Resque.should_receive(:workers).and_return [shutdown_worker, @worker, @worker]
41
+ subject.send(:current_workers).should == [@worker, @worker]
42
+ end
43
+
44
+ it "does not set workers that have the queue included with others" do
45
+ other_worker = Resque::Worker.new(:other, :test)
46
+ Resque.should_receive(:workers).and_return [@worker, other_worker, @worker]
47
+ subject.send(:current_workers).should == [@worker, @worker]
48
+ end
49
+
50
+ it "finds workers working on multiple queues if specified" do
51
+ other_worker = Resque::Worker.new(:other, :test)
52
+ Resque::Plugins::Director::Config.queue = [:other,:test]
53
+ Resque.should_receive(:workers).and_return [@worker, other_worker]
54
+ subject.send(:current_workers).should == [other_worker]
27
55
  end
28
56
  end
29
57
 
@@ -31,41 +59,41 @@ describe Resque::Plugins::Director::WorkerTracker do
31
59
  it "should limit the workers to be removed to not go below minimum allowed workers" do
32
60
  Resque.should_receive(:workers).and_return [@worker, @worker]
33
61
  Resque::Plugins::Director::Config.setup :min_workers => 1
34
- subject.new.total_to_remove(2).should == 1
62
+ subject.total_to_remove(2).should == 1
35
63
  end
36
64
 
37
65
  it "always keeps at least one worker" do
38
66
  Resque.should_receive(:workers).and_return [@worker, @worker, @worker]
39
67
  Resque::Plugins::Director::Config.setup :min_workers => 0
40
- subject.new.total_to_remove(2).should == 2
68
+ subject.total_to_remove(2).should == 2
41
69
  end
42
70
 
43
71
  it "should return zero if there is only one worker working" do
44
72
  Resque.should_receive(:workers).and_return [@worker]
45
73
  Resque::Plugins::Director::Config.setup :min_workers => 0
46
- subject.new.total_to_remove(1).should == 0
74
+ subject.total_to_remove(1).should == 0
47
75
  end
48
76
  end
49
77
 
50
78
 
51
79
  describe "#total_to_add" do
52
80
  before do
53
- Resque.should_receive(:workers).and_return [@worker, @worker]
81
+ Resque.stub(:workers).and_return [@worker, @worker]
54
82
  end
55
83
 
56
84
  it "should limit the workers to be removed to not go below minimum allowed workers" do
57
85
  Resque::Plugins::Director::Config.setup :max_workers => 3
58
- subject.new.total_to_add(2).should == 1
86
+ subject.total_to_add(2).should == 1
59
87
  end
60
88
 
61
89
  it "should allow the workers to be removed if it stays above the minimum" do
62
90
  Resque::Plugins::Director::Config.setup :max_workers => 4
63
- subject.new.total_to_add(2).should == 2
91
+ subject.total_to_add(2).should == 2
64
92
  end
65
93
 
66
94
  it "should not limit workers added if max_workers is zero" do
67
95
  Resque::Plugins::Director::Config.setup :max_workers => 0
68
- subject.new.total_to_add(200).should == 200
96
+ subject.total_to_add(200).should == 200
69
97
  end
70
98
  end
71
99
 
@@ -73,25 +101,25 @@ describe Resque::Plugins::Director::WorkerTracker do
73
101
  it "should return the number of workers needed to meet the minimum requirement" do
74
102
  Resque.should_receive(:workers).and_return [@worker, @worker]
75
103
  Resque::Plugins::Director::Config.setup :min_workers => 4
76
- subject.new.total_for_requirements.should == 2
104
+ subject.total_for_requirements.should == 2
77
105
  end
78
106
 
79
107
  it "should return the number of workers needed to meet the maximum requirement" do
80
- Resque.should_receive(:workers).and_return [@worker, @worker]
108
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker, @worker]
81
109
  Resque::Plugins::Director::Config.setup :max_workers => 1
82
- subject.new.total_for_requirements.should == -1
110
+ subject.total_for_requirements.should == -1
83
111
  end
84
112
 
85
113
  it "should return 1 no workers are running and the minimum is zero" do
86
114
  Resque.should_receive(:workers).and_return []
87
115
  Resque::Plugins::Director::Config.setup :min_workers => 0
88
- subject.new.total_for_requirements.should == 1
116
+ subject.total_for_requirements.should == 1
89
117
  end
90
118
 
91
119
  it "should return 0 if number of workers is within requirements" do
92
- Resque.should_receive(:workers).and_return [@worker, @worker]
120
+ Resque.should_receive(:workers).any_number_of_times.and_return [@worker, @worker]
93
121
  Resque::Plugins::Director::Config.setup :min_workers => 1, :max_workers => 3
94
- subject.new.total_for_requirements.should == 0
122
+ subject.total_for_requirements.should == 0
95
123
  end
96
124
  end
97
125
 
@@ -99,19 +127,19 @@ describe Resque::Plugins::Director::WorkerTracker do
99
127
  it "should return the number to scale down to go to the minimum" do
100
128
  Resque.should_receive(:workers).and_return [@worker, @worker, @worker]
101
129
  Resque::Plugins::Director::Config.setup :min_workers => 2
102
- subject.new.total_to_go_to_minimum.should == 1
130
+ subject.total_to_go_to_minimum.should == 1
103
131
  end
104
132
 
105
133
  it "should return zero if already at the minimum" do
106
134
  Resque.should_receive(:workers).and_return [@worker, @worker, @worker]
107
135
  Resque::Plugins::Director::Config.setup :min_workers => 3
108
- subject.new.total_to_go_to_minimum.should == 0
136
+ subject.total_to_go_to_minimum.should == 0
109
137
  end
110
138
 
111
139
  it "should return zero if below the minimum" do
112
140
  Resque.should_receive(:workers).and_return [@worker, @worker, @worker]
113
141
  Resque::Plugins::Director::Config.setup :min_workers => 4
114
- subject.new.total_to_go_to_minimum.should == 0
142
+ subject.total_to_go_to_minimum.should == 0
115
143
  end
116
144
  end
117
145
 
@@ -121,42 +149,8 @@ describe Resque::Plugins::Director::WorkerTracker do
121
149
  worker2 = Resque::Worker.new(:test)
122
150
  pid = worker2.to_s.split(":")[1].to_i
123
151
  Resque.should_receive(:workers).and_return [@worker, worker2]
124
- tracker = Resque::Plugins::Director::WorkerTracker.new
125
152
 
126
- tracker.valid_worker_pids.should == [pid]
127
- end
128
- end
129
-
130
- describe "#initialize" do
131
- it "sets the workers from the queue" do
132
- Resque.should_receive(:workers).and_return [@worker, @worker, @worker]
133
- subject.new.workers.should == [@worker, @worker, @worker]
134
- end
135
-
136
- it "does not set workers from different queues" do
137
- other_worker = Resque::Worker.new(:other)
138
- Resque.should_receive(:workers).and_return [@worker, other_worker, @worker]
139
- subject.new.workers.should == [@worker, @worker]
140
- end
141
-
142
- it "does not set workers that are scheduled for shutdow" do
143
- shutdown_worker = Resque::Worker.new(:test)
144
- shutdown_worker.shutdown
145
- Resque.should_receive(:workers).and_return [shutdown_worker, @worker, @worker]
146
- subject.new.workers.should == [@worker, @worker]
147
- end
148
-
149
- it "does not set workers that have the queue included with others" do
150
- other_worker = Resque::Worker.new(:other, :test)
151
- Resque.should_receive(:workers).and_return [@worker, other_worker, @worker]
152
- subject.new.workers.should == [@worker, @worker]
153
- end
154
-
155
- it "finds workers working on multiple queues if specified" do
156
- other_worker = Resque::Worker.new(:other, :test)
157
- Resque::Plugins::Director::Config.queue = [:other,:test]
158
- Resque.should_receive(:workers).and_return [@worker, other_worker]
159
- subject.new.workers.should == [other_worker]
153
+ subject.valid_worker_pids.should == [pid]
160
154
  end
161
155
  end
162
156
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque-director
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 2
9
- - 2
10
- version: 2.2.2
9
+ - 3
10
+ version: 2.2.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Nolan Frausto
@@ -15,9 +15,10 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-09 00:00:00 Z
18
+ date: 2011-10-13 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
+ type: :runtime
21
22
  requirement: &id001 !ruby/object:Gem::Requirement
22
23
  none: false
23
24
  requirements:
@@ -31,8 +32,8 @@ dependencies:
31
32
  version_requirements: *id001
32
33
  name: resque
33
34
  prerelease: false
34
- type: :runtime
35
35
  - !ruby/object:Gem::Dependency
36
+ type: :development
36
37
  requirement: &id002 !ruby/object:Gem::Requirement
37
38
  none: false
38
39
  requirements:
@@ -47,8 +48,8 @@ dependencies:
47
48
  version_requirements: *id002
48
49
  name: rspec
49
50
  prerelease: false
50
- type: :development
51
51
  - !ruby/object:Gem::Dependency
52
+ type: :development
52
53
  requirement: &id003 !ruby/object:Gem::Requirement
53
54
  none: false
54
55
  requirements:
@@ -63,8 +64,8 @@ dependencies:
63
64
  version_requirements: *id003
64
65
  name: bundler
65
66
  prerelease: false
66
- type: :development
67
67
  - !ruby/object:Gem::Dependency
68
+ type: :development
68
69
  requirement: &id004 !ruby/object:Gem::Requirement
69
70
  none: false
70
71
  requirements:
@@ -79,8 +80,8 @@ dependencies:
79
80
  version_requirements: *id004
80
81
  name: jeweler
81
82
  prerelease: false
82
- type: :development
83
83
  - !ruby/object:Gem::Dependency
84
+ type: :development
84
85
  requirement: &id005 !ruby/object:Gem::Requirement
85
86
  none: false
86
87
  requirements:
@@ -93,8 +94,8 @@ dependencies:
93
94
  version_requirements: *id005
94
95
  name: rcov
95
96
  prerelease: false
96
- type: :development
97
97
  - !ruby/object:Gem::Dependency
98
+ type: :development
98
99
  requirement: &id006 !ruby/object:Gem::Requirement
99
100
  none: false
100
101
  requirements:
@@ -109,8 +110,8 @@ dependencies:
109
110
  version_requirements: *id006
110
111
  name: yajl-ruby
111
112
  prerelease: false
112
- type: :development
113
113
  - !ruby/object:Gem::Dependency
114
+ type: :development
114
115
  requirement: &id007 !ruby/object:Gem::Requirement
115
116
  none: false
116
117
  requirements:
@@ -125,7 +126,6 @@ dependencies:
125
126
  version_requirements: *id007
126
127
  name: json
127
128
  prerelease: false
128
- type: :development
129
129
  description: "resque plugin for automatically scaling workers based on the amount of time it takes a job to go through the queue and/or the length of the queue "
130
130
  email: nrfrausto@gmail.com
131
131
  executables: []
@@ -136,8 +136,8 @@ extra_rdoc_files:
136
136
  - LICENSE.txt
137
137
  - README.rdoc
138
138
  files:
139
- - .document
140
139
  - Gemfile
140
+ - HISTORY.md
141
141
  - LICENSE.txt
142
142
  - README.rdoc
143
143
  - Rakefile
@@ -186,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
186
  requirements: []
187
187
 
188
188
  rubyforge_project:
189
- rubygems_version: 1.8.8
189
+ rubygems_version: 1.8.6
190
190
  signing_key:
191
191
  specification_version: 3
192
192
  summary: A resque plugin for automatically scaling workers
data/.document DELETED
@@ -1,5 +0,0 @@
1
- lib/**/*.rb
2
- bin/*
3
- -
4
- features/**/*.feature
5
- LICENSE.txt