resque-director 1.1.0 → 2.0.0
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.rdoc +14 -6
- data/VERSION +1 -1
- data/lib/resque/plugins/director/extra_hooks.rb +41 -0
- data/lib/resque/plugins/director/scaler.rb +6 -3
- data/lib/resque/plugins/director.rb +45 -84
- data/lib/resque-director.rb +1 -1
- data/resque-director.gemspec +5 -5
- data/spec/resque/plugins/director/extra_hooks_spec.rb +46 -0
- data/spec/resque/plugins/director/scaler_spec.rb +12 -7
- data/spec/resque/plugins/director_spec.rb +18 -40
- data/spec/support/jobs.rb +14 -0
- metadata +8 -8
- data/lib/resque/plugins/director/lifecycle.rb +0 -35
- data/spec/resque/plugins/director/lifecycle_spec.rb +0 -38
- data/spec/support/test_job.rb +0 -7
data/README.rdoc
CHANGED
@@ -10,12 +10,12 @@ resque-director does not operate on workers that serve multiple queues, and does
|
|
10
10
|
|
11
11
|
== Usage
|
12
12
|
|
13
|
-
When creating your jobs you should
|
13
|
+
When creating your jobs you should extend Resque::Plugins::Director and add direction options.
|
14
14
|
|
15
15
|
For Example:
|
16
16
|
|
17
17
|
class Job
|
18
|
-
|
18
|
+
extend Resque::Plugins::Director
|
19
19
|
direct :min_workers => 2, :max_workers => 4, :max_time => 60, :max_queue => 10, :wait_time => 30
|
20
20
|
@queue = :test
|
21
21
|
|
@@ -37,15 +37,18 @@ For Example:
|
|
37
37
|
|
38
38
|
=== Worker Options
|
39
39
|
|
40
|
-
<b>start_override</b>:: This
|
40
|
+
<b>start_override</b>:: This option takes a lambda closure that accepts the queue as an argument, the block you pass in will be responsible for starting a SINGLE worker allowing you to fully customize the starting of a worker. By default the system command "QUEUE=queue_name rake resque:work &" is run, where queue_name is whatever queue the job is running.
|
41
41
|
|
42
|
-
<b>stop_override</b>:: This
|
42
|
+
<b>stop_override</b>:: This option takes a lambda closure that accepts the queue as an argument, the block you pass in will be responsible for stopping a SINGLE worker allowing you to fully customize the stopping of a worker. Process.kill("QUIT", worker_pid) is used to stop the worker by default, where worker_pid is the process id of a worker.
|
43
43
|
|
44
44
|
=== Starting/Stopping Workers Example
|
45
45
|
|
46
46
|
class Job
|
47
|
-
|
48
|
-
|
47
|
+
extend Resque::Plugins::Director
|
48
|
+
|
49
|
+
start_block = lambda{|queue| system("start_#{queue}")}
|
50
|
+
stop_block = lambda{|queue| system("stop_#{queue}")}
|
51
|
+
direct :start_override => start_block, :stop_override => stop_block
|
49
52
|
@queue = :test
|
50
53
|
|
51
54
|
#rest of your Job class here
|
@@ -70,6 +73,11 @@ To add director logging you can pass a logger as an option. It will prepend all
|
|
70
73
|
* If a max_worker is less than min_worker then the default for max_worker will be used (there will be no maximum).
|
71
74
|
* If a min_workers is set to anything less than 1 then it will be treated as 0.
|
72
75
|
|
76
|
+
=== Requirements
|
77
|
+
|
78
|
+
* resque-director requires resque ~> 1.14.0.
|
79
|
+
* resque-director may be incompatible with gems that modify resque's push/pop functionality.
|
80
|
+
|
73
81
|
|
74
82
|
== Contributing to resque-reconnect
|
75
83
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Resque
|
2
|
+
module Plugins
|
3
|
+
module Director
|
4
|
+
module ExtraHooks
|
5
|
+
|
6
|
+
def self.included(base) #:nodoc:
|
7
|
+
base.class_eval do
|
8
|
+
alias_method :original_pop, :pop
|
9
|
+
alias_method :original_push, :push
|
10
|
+
extend ClassMethods
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def push(queue, item)
|
16
|
+
item[:created_at] = Time.now.utc.to_i if item.respond_to?(:[]=)
|
17
|
+
original_push queue, item
|
18
|
+
end
|
19
|
+
|
20
|
+
def pop(queue)
|
21
|
+
job = original_pop(queue)
|
22
|
+
begin
|
23
|
+
timestamp = job['created_at']
|
24
|
+
start_time = timestamp.nil? ? Time.now.utc : Time.at(timestamp.to_i).utc
|
25
|
+
job_class = constantize(job['class'])
|
26
|
+
if job_class && job_class.respond_to?(:after_pop_direct_workers) && job_class.respond_to?(:direct)
|
27
|
+
job_class.after_pop_direct_workers(start_time)
|
28
|
+
end
|
29
|
+
rescue
|
30
|
+
end
|
31
|
+
job
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module Resque
|
40
|
+
include Resque::Plugins::Director::ExtraHooks
|
41
|
+
end
|
@@ -53,14 +53,17 @@ module Resque
|
|
53
53
|
|
54
54
|
def start(number_of_workers)
|
55
55
|
Config.log("starting #{number_of_workers} workers on queue:#{Config.queue}") if number_of_workers > 0
|
56
|
-
|
57
|
-
|
56
|
+
if Config.start_override
|
57
|
+
number_of_workers.times { Config.start_override.call(Config.queue) }
|
58
|
+
else
|
59
|
+
number_of_workers.times { system("QUEUE=#{Config.queue} rake resque:work &") }
|
60
|
+
end
|
58
61
|
end
|
59
62
|
|
60
63
|
def stop(tracker, number_of_workers)
|
61
64
|
Config.log("stopping #{number_of_workers} workers on queue:#{Config.queue}") if number_of_workers > 0
|
62
65
|
if Config.stop_override
|
63
|
-
number_of_workers.times {
|
66
|
+
number_of_workers.times {Config.stop_override.call(Config.queue) }
|
64
67
|
else
|
65
68
|
valid_workers = tracker.workers.select{|w| w.hostname == `hostname`.chomp}
|
66
69
|
worker_pids = valid_workers[0...number_of_workers].map(&:pid)
|
@@ -1,95 +1,56 @@
|
|
1
1
|
module Resque
|
2
2
|
module Plugins
|
3
3
|
module Director
|
4
|
-
|
5
|
-
|
6
|
-
base.extend ClassMethods
|
7
|
-
base.overwrite_perform
|
8
|
-
base.instance_eval do
|
9
|
-
def singleton_method_added(name)
|
10
|
-
return if name != :perform
|
11
|
-
overwrite_perform
|
12
|
-
end
|
13
|
-
end
|
4
|
+
def direct(options={})
|
5
|
+
Config.setup(options)
|
14
6
|
end
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
klass.instance_eval do
|
25
|
-
def custom_perform(*args)
|
26
|
-
args.pop unless retrieve_timestamp(args.last).nil?
|
27
|
-
original_perform(*args)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class << klass
|
32
|
-
alias_method :original_perform, :perform
|
33
|
-
alias_method :perform, :custom_perform
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def after_enqueue_scale_workers(*args)
|
40
|
-
Config.queue = @queue.to_s
|
41
|
-
Scaler.scale_within_requirements
|
42
|
-
end
|
43
|
-
|
44
|
-
def before_perform_direct_workers(*args)
|
45
|
-
return unless scaling_config_set?
|
46
|
-
Config.queue = @queue.to_s
|
47
|
-
time_stamp = retrieve_timestamp(args.pop)
|
48
|
-
start_time = time_stamp.nil? ? Time.now.utc : Time.at(time_stamp.to_i).utc
|
49
|
-
|
50
|
-
time_through_queue = Time.now.utc - start_time
|
51
|
-
jobs_in_queue = Resque.size(@queue.to_s)
|
52
|
-
|
53
|
-
if scale_up?(time_through_queue, jobs_in_queue)
|
54
|
-
Scaler.scale_up
|
55
|
-
elsif scale_down?(time_through_queue, jobs_in_queue)
|
56
|
-
Scaler.scale_down
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def after_perform_direct_workers(*args)
|
61
|
-
jobs_in_queue = Resque.size(@queue.to_s)
|
62
|
-
Scaler.scale_down_to_minimum if jobs_in_queue == 0
|
63
|
-
end
|
64
|
-
|
65
|
-
def on_failure_direct_workers(*args)
|
66
|
-
jobs_in_queue = Resque.size(@queue.to_s)
|
67
|
-
Scaler.scale_down_to_minimum if jobs_in_queue == 0
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
7
|
+
|
8
|
+
def after_enqueue_scale_workers(*args)
|
9
|
+
Config.queue = @queue.to_s
|
10
|
+
Scaler.scale_within_requirements
|
11
|
+
end
|
12
|
+
|
13
|
+
def after_pop_direct_workers(start_time=Time.now.utc)
|
14
|
+
return unless scaling_config_set?
|
15
|
+
Config.queue = @queue.to_s
|
71
16
|
|
72
|
-
|
73
|
-
|
74
|
-
timestamp['resdirecttime'] || timestamp[:resdirecttime]
|
75
|
-
end
|
76
|
-
|
77
|
-
def scaling_config_set?
|
78
|
-
Config.max_time > 0 || Config.max_queue > 0
|
79
|
-
end
|
17
|
+
time_through_queue = Time.now.utc - start_time
|
18
|
+
jobs_in_queue = Resque.size(@queue.to_s)
|
80
19
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
def scale_down?(time_through_queue, jobs_in_queue)
|
88
|
-
time_limits = Config.max_time > 0 && time_through_queue < (Config.max_time/2)
|
89
|
-
queue_limits = Config.max_queue > 0 && jobs_in_queue < (Config.max_queue/2)
|
90
|
-
(Config.max_time <= 0 || time_limits) && (Config.max_queue <= 0 || queue_limits)
|
20
|
+
if scale_up?(time_through_queue, jobs_in_queue)
|
21
|
+
Scaler.scale_up
|
22
|
+
elsif scale_down?(time_through_queue, jobs_in_queue)
|
23
|
+
Scaler.scale_down
|
91
24
|
end
|
92
25
|
end
|
26
|
+
|
27
|
+
def after_perform_direct_workers(*args)
|
28
|
+
jobs_in_queue = Resque.size(@queue.to_s)
|
29
|
+
Scaler.scale_down_to_minimum if jobs_in_queue == 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def on_failure_direct_workers(*args)
|
33
|
+
jobs_in_queue = Resque.size(@queue.to_s)
|
34
|
+
Scaler.scale_down_to_minimum if jobs_in_queue == 0
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def scaling_config_set?
|
40
|
+
Config.max_time > 0 || Config.max_queue > 0
|
41
|
+
end
|
42
|
+
|
43
|
+
def scale_up?(time_through_queue, jobs_in_queue)
|
44
|
+
time_limits = Config.max_time > 0 && time_through_queue > Config.max_time
|
45
|
+
queue_limits = Config.max_queue > 0 && jobs_in_queue > Config.max_queue
|
46
|
+
time_limits || queue_limits
|
47
|
+
end
|
48
|
+
|
49
|
+
def scale_down?(time_through_queue, jobs_in_queue)
|
50
|
+
time_limits = Config.max_time > 0 && time_through_queue < (Config.max_time/2)
|
51
|
+
queue_limits = Config.max_queue > 0 && jobs_in_queue < (Config.max_queue/2)
|
52
|
+
(Config.max_time <= 0 || time_limits) && (Config.max_queue <= 0 || queue_limits)
|
53
|
+
end
|
93
54
|
end
|
94
55
|
end
|
95
56
|
end
|
data/lib/resque-director.rb
CHANGED
data/resque-director.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{resque-director}
|
8
|
-
s.version = "
|
8
|
+
s.version = "2.0.0"
|
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-08-
|
12
|
+
s.date = %q{2011-08-24}
|
13
13
|
s.description = %q{resque plugin for dynamically adding/removing workers to a queue}
|
14
14
|
s.email = %q{nrfrausto@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -27,18 +27,18 @@ Gem::Specification.new do |s|
|
|
27
27
|
"lib/resque-director.rb",
|
28
28
|
"lib/resque/plugins/director.rb",
|
29
29
|
"lib/resque/plugins/director/config.rb",
|
30
|
-
"lib/resque/plugins/director/
|
30
|
+
"lib/resque/plugins/director/extra_hooks.rb",
|
31
31
|
"lib/resque/plugins/director/scaler.rb",
|
32
32
|
"lib/resque/plugins/director/worker_tracker.rb",
|
33
33
|
"resque-director.gemspec",
|
34
34
|
"spec/redis-test.conf",
|
35
35
|
"spec/resque/plugins/director/config_spec.rb",
|
36
|
-
"spec/resque/plugins/director/
|
36
|
+
"spec/resque/plugins/director/extra_hooks_spec.rb",
|
37
37
|
"spec/resque/plugins/director/scaler_spec.rb",
|
38
38
|
"spec/resque/plugins/director/worker_tracker_spec.rb",
|
39
39
|
"spec/resque/plugins/director_spec.rb",
|
40
40
|
"spec/spec_helper.rb",
|
41
|
-
"spec/support/
|
41
|
+
"spec/support/jobs.rb"
|
42
42
|
]
|
43
43
|
s.homepage = %q{http://github.com/frausto/resque-director}
|
44
44
|
s.licenses = [%q{MIT}]
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Resque::Plugins::Director::ExtraHooks do
|
4
|
+
subject { Resque::Plugins::Director::ExtraHooks }
|
5
|
+
|
6
|
+
before do
|
7
|
+
Resque::Plugins::Director::Config.queue = "test"
|
8
|
+
@now = Time.now
|
9
|
+
Time.stub(:now => @now)
|
10
|
+
@timestamp = @now.utc.to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#push" do
|
14
|
+
it "should add the start timestamp to the end of the job" do
|
15
|
+
Resque.enqueue(TestJob, "arg1")
|
16
|
+
Resque.redis.lindex("queue:test",0).should =~ /^\{.*\"created_at\":#{@timestamp}/
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#pop" do
|
21
|
+
it "should direct workers using the timestamp" do
|
22
|
+
Resque.enqueue(TestJob, "arg1")
|
23
|
+
expected_time = Time.at(@timestamp).utc
|
24
|
+
TestJob.should_receive(:after_pop_direct_workers).with(expected_time)
|
25
|
+
Resque.pop("test").should == {"args"=>["arg1"], "class"=>"TestJob", "created_at"=>@timestamp}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should direct workers with current time if no start time" do
|
29
|
+
Resque.should_receive(:original_pop).and_return({'args' => [], 'class' => 'TestJob'})
|
30
|
+
TestJob.should_receive(:after_pop_direct_workers).with(@now)
|
31
|
+
Resque.pop("test").should == {"args"=>[], "class"=>"TestJob"}
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not direct workers if the job is not directed" do
|
35
|
+
Resque.enqueue(NonDirectedTestJob, "arg1")
|
36
|
+
NonDirectedTestJob.should_not_receive(:after_pop_direct_workers)
|
37
|
+
Resque.pop("non_directed").should include({"args"=>["arg1"], "class"=>"NonDirectedTestJob"})
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return the job properly if an exception is thrown in the direction logic" do
|
41
|
+
Resque.enqueue(TestJob, "arg1")
|
42
|
+
TestJob.should_receive(:after_pop_direct_workers).and_throw(:Exception)
|
43
|
+
Resque.pop("test").should include({"args"=>["arg1"], "class"=>"TestJob"})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -25,8 +25,9 @@ describe Resque::Plugins::Director::Scaler do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should override the entire comand" do
|
28
|
-
|
29
|
-
|
28
|
+
test_block = lambda {|queue| }
|
29
|
+
Resque::Plugins::Director::Config.setup :start_override => test_block
|
30
|
+
test_block.should_receive(:call).with("test")
|
30
31
|
subject.scale_up
|
31
32
|
end
|
32
33
|
end
|
@@ -135,12 +136,14 @@ describe Resque::Plugins::Director::Scaler do
|
|
135
136
|
subject.send(:stop, tracker, 1)
|
136
137
|
end
|
137
138
|
|
138
|
-
it "should use the stop
|
139
|
-
|
139
|
+
it "should use the stop block to stop a worker if set" do
|
140
|
+
test_block = lambda {|queue| }
|
141
|
+
Resque::Plugins::Director::Config.setup :stop_override => test_block, :min_workers => 0
|
142
|
+
|
140
143
|
Resque.should_receive(:workers).and_return [@worker]
|
141
144
|
tracker = Resque::Plugins::Director::WorkerTracker.new
|
142
145
|
|
143
|
-
|
146
|
+
test_block.should_receive(:call).with("test")
|
144
147
|
Process.should_not_receive(:kill)
|
145
148
|
subject.send(:stop, tracker, 1)
|
146
149
|
end
|
@@ -174,12 +177,14 @@ describe Resque::Plugins::Director::Scaler do
|
|
174
177
|
end
|
175
178
|
|
176
179
|
it "ignores hostname if using custom stop script" do
|
177
|
-
|
180
|
+
test_block = lambda {|queue| }
|
181
|
+
Resque::Plugins::Director::Config.setup :stop_override => test_block, :min_workers => 0
|
182
|
+
|
178
183
|
@worker.stub!(:hostname => "different_machine")
|
179
184
|
Resque.should_receive(:workers).and_return [@worker]
|
180
185
|
tracker = Resque::Plugins::Director::WorkerTracker.new
|
181
186
|
|
182
|
-
|
187
|
+
test_block.should_receive(:call).with("test")
|
183
188
|
Process.should_not_receive(:kill)
|
184
189
|
subject.send(:stop, tracker, 1)
|
185
190
|
end
|
@@ -48,50 +48,50 @@ describe Resque::Plugins::Director do
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
describe "#
|
51
|
+
describe "#after_pop_direct_workers" do
|
52
52
|
describe "with time" do
|
53
53
|
before do
|
54
|
-
@start_time =
|
54
|
+
@start_time = (Time.now - 10).utc
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should set the queue if not set" do
|
58
58
|
TestJob.direct :max_time => 20
|
59
59
|
Resque::Plugins::Director::Config.queue = nil
|
60
|
-
TestJob.
|
60
|
+
TestJob.after_pop_direct_workers(@start_time)
|
61
61
|
Resque::Plugins::Director::Config.queue.should == "test"
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should not start workers if max_time is not set" do
|
65
65
|
Resque::Plugins::Director::Scaler.should_not_receive(:scale_up)
|
66
|
-
TestJob.
|
66
|
+
TestJob.after_pop_direct_workers(@start_time)
|
67
67
|
end
|
68
68
|
|
69
69
|
it "should not start a worker if the time since it took is less than max_time" do
|
70
70
|
TestJob.direct :max_time => 20
|
71
71
|
|
72
72
|
Resque::Plugins::Director::Scaler.should_not_receive(:scale_up)
|
73
|
-
TestJob.
|
73
|
+
TestJob.after_pop_direct_workers(@start_time)
|
74
74
|
end
|
75
75
|
|
76
76
|
it "should add a worker if the time it takes the job to go through the queue is too long" do
|
77
77
|
TestJob.direct :max_time => 5
|
78
78
|
Resque::Plugins::Director::Scaler.should_receive(:scale_up)
|
79
79
|
|
80
|
-
TestJob.
|
80
|
+
TestJob.after_pop_direct_workers(@start_time)
|
81
81
|
end
|
82
82
|
|
83
83
|
it "should remove a worker if the queue time is below half the max" do
|
84
84
|
TestJob.direct :max_time => 25
|
85
85
|
|
86
86
|
Resque::Plugins::Director::Scaler.should_receive(:scale_down)
|
87
|
-
TestJob.
|
87
|
+
TestJob.after_pop_direct_workers(@start_time)
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
91
|
describe "with queue length" do
|
92
92
|
it "should not start workers if max_queue is not set" do
|
93
93
|
Resque::Plugins::Director::Scaler.should_not_receive(:scale_up)
|
94
|
-
TestJob.
|
94
|
+
TestJob.after_pop_direct_workers
|
95
95
|
end
|
96
96
|
|
97
97
|
it "should not start worker if the queue length is less than max_queue" do
|
@@ -99,7 +99,7 @@ describe Resque::Plugins::Director do
|
|
99
99
|
Resque.enqueue(TestJob)
|
100
100
|
|
101
101
|
Resque::Plugins::Director::Scaler.should_not_receive(:scale_up)
|
102
|
-
TestJob.
|
102
|
+
TestJob.after_pop_direct_workers
|
103
103
|
end
|
104
104
|
|
105
105
|
it "should start worker if the queue length is greater than max_queue" do
|
@@ -107,7 +107,7 @@ describe Resque::Plugins::Director do
|
|
107
107
|
2.times { Resque.enqueue(TestJob) }
|
108
108
|
|
109
109
|
Resque::Plugins::Director::Scaler.should_receive(:scale_up)
|
110
|
-
TestJob.
|
110
|
+
TestJob.after_pop_direct_workers
|
111
111
|
end
|
112
112
|
|
113
113
|
it "should remove a worker if the queue length is below half the max" do
|
@@ -115,13 +115,13 @@ describe Resque::Plugins::Director do
|
|
115
115
|
1.times { Resque.enqueue(TestJob) }
|
116
116
|
|
117
117
|
Resque::Plugins::Director::Scaler.should_receive(:scale_down)
|
118
|
-
TestJob.
|
118
|
+
TestJob.after_pop_direct_workers
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
122
|
describe "with length and time" do
|
123
123
|
before do
|
124
|
-
@start_time =
|
124
|
+
@start_time = (Time.now - 10).utc
|
125
125
|
end
|
126
126
|
|
127
127
|
it "should add worker if only time constraint fails" do
|
@@ -129,7 +129,7 @@ describe Resque::Plugins::Director do
|
|
129
129
|
Resque.enqueue(TestJob)
|
130
130
|
Resque::Plugins::Director::Scaler.should_receive(:scale_up)
|
131
131
|
|
132
|
-
TestJob.
|
132
|
+
TestJob.after_pop_direct_workers(@start_time)
|
133
133
|
end
|
134
134
|
|
135
135
|
it "should add worker if only queue length constraint fails" do
|
@@ -137,7 +137,7 @@ describe Resque::Plugins::Director do
|
|
137
137
|
2.times { Resque.enqueue(TestJob) }
|
138
138
|
|
139
139
|
Resque::Plugins::Director::Scaler.should_receive(:scale_up)
|
140
|
-
TestJob.
|
140
|
+
TestJob.after_pop_direct_workers
|
141
141
|
end
|
142
142
|
|
143
143
|
it "should not scale down if a worker is being scaled up due to time" do
|
@@ -146,7 +146,7 @@ describe Resque::Plugins::Director do
|
|
146
146
|
|
147
147
|
Resque::Plugins::Director::Scaler.should_receive(:scale_up)
|
148
148
|
Resque::Plugins::Director::Scaler.should_not_receive(:scale_down)
|
149
|
-
TestJob.
|
149
|
+
TestJob.after_pop_direct_workers(@start_time)
|
150
150
|
end
|
151
151
|
|
152
152
|
it "should not scale down if a worker is being scaled up due to queue" do
|
@@ -155,7 +155,7 @@ describe Resque::Plugins::Director do
|
|
155
155
|
|
156
156
|
Resque::Plugins::Director::Scaler.should_receive(:scale_up)
|
157
157
|
Resque::Plugins::Director::Scaler.should_not_receive(:scale_down)
|
158
|
-
TestJob.
|
158
|
+
TestJob.after_pop_direct_workers
|
159
159
|
end
|
160
160
|
|
161
161
|
it "should not scale if only one limit is met" do
|
@@ -164,35 +164,13 @@ describe Resque::Plugins::Director do
|
|
164
164
|
|
165
165
|
Resque::Plugins::Director::Scaler.should_not_receive(:scale_up)
|
166
166
|
Resque::Plugins::Director::Scaler.should_not_receive(:scale_down)
|
167
|
-
TestJob.
|
167
|
+
TestJob.after_pop_direct_workers(@start_time)
|
168
168
|
end
|
169
169
|
|
170
170
|
it "should not scale if no configuration options are set" do
|
171
171
|
Resque::Plugins::Director::Scaler.should_not_receive(:scale_up)
|
172
172
|
Resque::Plugins::Director::Scaler.should_not_receive(:scale_down)
|
173
|
-
TestJob.
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
describe "crazy meta custom_perform" do
|
178
|
-
it "should strip out the timestamp from the args before calling the original perform" do
|
179
|
-
TestJob.should_receive(:original_perform).with("arg")
|
180
|
-
TestJob.perform("arg", {:resdirecttime => 1234})
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should strip out timestamp if it is not a symbol" do
|
184
|
-
TestJob.should_receive(:original_perform).with("arg")
|
185
|
-
TestJob.perform("arg", {'resdirecttime' => 1234})
|
186
|
-
end
|
187
|
-
|
188
|
-
it "should not strip out any args if timestamp does not exist" do
|
189
|
-
TestJob.should_receive(:original_perform).with("arg", {:test => 123})
|
190
|
-
TestJob.perform("arg", {:test => 123})
|
191
|
-
end
|
192
|
-
|
193
|
-
it "should not strip out any args if timestamp does not exist" do
|
194
|
-
TestJob.should_receive(:original_perform).with("arg")
|
195
|
-
TestJob.perform("arg")
|
173
|
+
TestJob.after_pop_direct_workers
|
196
174
|
end
|
197
175
|
end
|
198
176
|
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:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
|
-
-
|
8
|
-
- 1
|
7
|
+
- 2
|
9
8
|
- 0
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 2.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Nolan Frausto
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-08-
|
18
|
+
date: 2011-08-24 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
requirement: &id001 !ruby/object:Gem::Requirement
|
@@ -115,18 +115,18 @@ files:
|
|
115
115
|
- lib/resque-director.rb
|
116
116
|
- lib/resque/plugins/director.rb
|
117
117
|
- lib/resque/plugins/director/config.rb
|
118
|
-
- lib/resque/plugins/director/
|
118
|
+
- lib/resque/plugins/director/extra_hooks.rb
|
119
119
|
- lib/resque/plugins/director/scaler.rb
|
120
120
|
- lib/resque/plugins/director/worker_tracker.rb
|
121
121
|
- resque-director.gemspec
|
122
122
|
- spec/redis-test.conf
|
123
123
|
- spec/resque/plugins/director/config_spec.rb
|
124
|
-
- spec/resque/plugins/director/
|
124
|
+
- spec/resque/plugins/director/extra_hooks_spec.rb
|
125
125
|
- spec/resque/plugins/director/scaler_spec.rb
|
126
126
|
- spec/resque/plugins/director/worker_tracker_spec.rb
|
127
127
|
- spec/resque/plugins/director_spec.rb
|
128
128
|
- spec/spec_helper.rb
|
129
|
-
- spec/support/
|
129
|
+
- spec/support/jobs.rb
|
130
130
|
homepage: http://github.com/frausto/resque-director
|
131
131
|
licenses:
|
132
132
|
- MIT
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Resque
|
2
|
-
module Plugins
|
3
|
-
module Director
|
4
|
-
module Lifecycle
|
5
|
-
|
6
|
-
def self.included(base) #:nodoc:
|
7
|
-
base.class_eval do
|
8
|
-
alias_method :push_without_lifecycle, :push
|
9
|
-
extend ClassMethods
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
module ClassMethods
|
14
|
-
def push(queue, item)
|
15
|
-
begin
|
16
|
-
if item.respond_to?(:[]=)
|
17
|
-
job_class = constantize(item[:class] || item['class'])
|
18
|
-
if job_class && job_class.ancestors.include?(Resque::Plugins::Director)
|
19
|
-
timestamp = {'resdirecttime' => Time.now.utc.to_i}
|
20
|
-
item[:args] = item[:args].push(timestamp)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
rescue
|
24
|
-
end
|
25
|
-
push_without_lifecycle queue, item
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
module Resque
|
34
|
-
include Resque::Plugins::Director::Lifecycle
|
35
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class TestNonDirectedJob
|
4
|
-
@queue = :non_direct
|
5
|
-
def self.perform
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
describe Resque::Plugins::Director::Lifecycle do
|
10
|
-
subject { Resque::Plugins::Director::Lifecycle }
|
11
|
-
|
12
|
-
before do
|
13
|
-
Resque::Plugins::Director::Config.queue = "test"
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "#lifecycle" do
|
17
|
-
it "should add the jobs timestamp at the end of the job args" do
|
18
|
-
now = Time.now
|
19
|
-
Time.stub(:now => now)
|
20
|
-
time_stamp = now.utc.to_i
|
21
|
-
|
22
|
-
Resque.enqueue(TestJob, "arg1")
|
23
|
-
Resque.pop("test").should == {"args"=>["arg1", {'resdirecttime' => time_stamp}], "class"=>"TestJob"}
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should not add job timestamps to non directed jobs" do
|
27
|
-
Resque.enqueue(TestNonDirectedJob, "arg1")
|
28
|
-
Resque.pop("non_direct").should == {"args"=>["arg1"], "class"=>"TestNonDirectedJob"}
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should not add job timestamps that throw exceptions to direction logic" do
|
32
|
-
TestNonDirectedJob.stub(:ancestors).and_throw(:Exception)
|
33
|
-
Resque.enqueue(TestNonDirectedJob, "arg1")
|
34
|
-
|
35
|
-
Resque.pop("non_direct").should == {"args"=>["arg1"], "class"=>"TestNonDirectedJob"}
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|