beanstalk_farmer 0.2.2 → 0.3.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/Changelog.md +19 -0
- data/README.md +6 -0
- data/lib/beanstalk_farmer/job.rb +34 -13
- data/lib/beanstalk_farmer/runner.rb +23 -16
- data/lib/beanstalk_farmer/service.rb +16 -5
- data/lib/beanstalk_farmer/version.rb +1 -1
- data/spec/beanstalk_farmer/job_spec.rb +102 -14
- data/spec/beanstalk_farmer/runner_spec.rb +10 -23
- data/spec/beanstalk_farmer/service_spec.rb +41 -7
- data/spec/integration/special_worker_spec.rb +57 -0
- data/spec/integration/working_spec.rb +15 -15
- data/spec/spec_helper.rb +1 -0
- metadata +9 -13
data/Changelog.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
## 0.3.0
|
2
|
+
|
3
|
+
* Allow for job handlers to return instructions on how to complete the job at
|
4
|
+
the queue level. Please see README.md for details.
|
5
|
+
|
6
|
+
## 0.2.3
|
7
|
+
|
8
|
+
* Refactored many objects to not use Singleton pattern. This was introducing
|
9
|
+
global state. This is not a good thing.
|
10
|
+
* Moved more behaviour into the Service layer.
|
11
|
+
* Improvements to test environment.
|
12
|
+
|
13
|
+
## 0.2.2
|
14
|
+
|
15
|
+
* Test environment improvments for OS X.
|
16
|
+
* Reserve timeouts handled correctly.
|
17
|
+
* Better errors. This may or may not break your app. Please test carefully.
|
18
|
+
* Support timeouts when reserving and working jobs in the Runner.
|
19
|
+
|
1
20
|
## 0.2.1
|
2
21
|
|
3
22
|
* Fix malformed gemspec. Gem should actually work now.
|
data/README.md
CHANGED
@@ -12,6 +12,12 @@ la Rack (e.g. `Proc`s, `procs`s). The payload of the job will be passed into
|
|
12
12
|
the arguments of this method. Bear in mind that the payload for a Beanstalk job
|
13
13
|
is de-serialized JSON.
|
14
14
|
|
15
|
+
By default all jobs will be deleted from the Beanstalk queue once completed.
|
16
|
+
This can be configured and changed by returning an Array of arguments from the
|
17
|
+
`#call` method. The first argument is expected to be the name of the method you
|
18
|
+
wish to invoke on a job (see `Beanstalk::Job`). All remaining arguments will be
|
19
|
+
passed to the named method.
|
20
|
+
|
15
21
|
For usage examples, see the examples directory in the source code.
|
16
22
|
|
17
23
|
## Development
|
data/lib/beanstalk_farmer/job.rb
CHANGED
@@ -5,7 +5,7 @@ module BeanstalkFarmer
|
|
5
5
|
class Job
|
6
6
|
include BeanstalkFarmer
|
7
7
|
|
8
|
-
attr_accessor :name, :args, :job
|
8
|
+
attr_accessor :name, :args, :job, :response
|
9
9
|
|
10
10
|
# @param [Beanstalk::Job] job A Beanstalk job that has been reserved to be
|
11
11
|
# worked upon
|
@@ -15,22 +15,18 @@ module BeanstalkFarmer
|
|
15
15
|
logger.info "JOB (#{name}) reserved"
|
16
16
|
end
|
17
17
|
|
18
|
+
# @return [#call] a class used to process the reserved job
|
19
|
+
def handler
|
20
|
+
self.class.handler_pool[name]
|
21
|
+
end
|
22
|
+
|
18
23
|
# Performs work for this job
|
19
24
|
def work
|
20
|
-
|
21
|
-
# TTR value. I'm not sure why at this point in time. Maybe to compensate
|
22
|
-
# for Job setup time.
|
23
|
-
Timeout.timeout(job.ttr) do
|
24
|
-
logger.info "JOB (#{name}) working"
|
25
|
-
handler = self.class.handler_pool[name]
|
26
|
-
handler.call(args)
|
27
|
-
end
|
25
|
+
do_some_work
|
28
26
|
rescue Timeout::Error
|
29
|
-
|
30
|
-
raise TimedOut, "#{name} could not finish in #{job.ttr} seconds"
|
27
|
+
handle_timeout!
|
31
28
|
ensure
|
32
|
-
|
33
|
-
logger.info "JOB (#{name}) done"
|
29
|
+
handle_job_response
|
34
30
|
end
|
35
31
|
|
36
32
|
# A pool of job handlers that can work on jobs in our queue
|
@@ -49,5 +45,30 @@ module BeanstalkFarmer
|
|
49
45
|
def set_name_and_arguments
|
50
46
|
self.name, self.args = MultiJson.decode(job.body)
|
51
47
|
end
|
48
|
+
|
49
|
+
def do_some_work
|
50
|
+
Timeout.timeout(job.ttr) do
|
51
|
+
logger.info "JOB (#{name}) working"
|
52
|
+
self.response = handler.call(args)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def handle_timeout!
|
57
|
+
logger.error "JOB (#{name}) out of time"
|
58
|
+
raise TimedOut, "#{name} could not finish in #{job.ttr} seconds"
|
59
|
+
end
|
60
|
+
|
61
|
+
def handle_job_response
|
62
|
+
if response.is_a?(Array)
|
63
|
+
logger.info "JOB (#{name}) done. Response: #{response.inspect}"
|
64
|
+
job.public_send(*response)
|
65
|
+
else
|
66
|
+
logger.info "JOB (#{name}) done. Deleting by default."
|
67
|
+
job.delete
|
68
|
+
end
|
69
|
+
rescue NoMethodError => e
|
70
|
+
logger.info "JOB (#{name}) done. Assuming delete from response: #{response.inspect}"
|
71
|
+
job.delete
|
72
|
+
end
|
52
73
|
end
|
53
74
|
end
|
@@ -1,10 +1,16 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
|
3
1
|
module BeanstalkFarmer
|
4
|
-
# Maps tube names to job handlers, and manages the run loop
|
2
|
+
# Maps tube names to job handlers, and manages the run loop.
|
3
|
+
#
|
4
|
+
# @example
|
5
|
+
#
|
6
|
+
# runner = BeanstalkFarmer::Runner.new
|
7
|
+
#
|
8
|
+
# runner.register_handlers do
|
9
|
+
# tube 'my_tube', lambda { |args| puts args {
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# runner.run!
|
5
13
|
class Runner
|
6
|
-
include Singleton
|
7
|
-
|
8
14
|
# @see Farmer::Job.handler_pool
|
9
15
|
def handler_pool
|
10
16
|
Job.handler_pool
|
@@ -12,7 +18,7 @@ module BeanstalkFarmer
|
|
12
18
|
|
13
19
|
# @return [Farmer::BeanstalkService] a connection to the Beanstalk queue
|
14
20
|
def service
|
15
|
-
@service ||= Service.
|
21
|
+
@service ||= Service.new
|
16
22
|
end
|
17
23
|
|
18
24
|
# Prepares tubes for watching
|
@@ -25,35 +31,36 @@ module BeanstalkFarmer
|
|
25
31
|
# @param [Integer] timeout (nil) The optional timeout to use when
|
26
32
|
# reserving a job
|
27
33
|
def reserve_and_work_job(timeout=nil)
|
28
|
-
|
29
|
-
job.work
|
34
|
+
service.reserve_and_work_job(timeout)
|
30
35
|
end
|
31
36
|
|
32
37
|
# Runs a loop looking for jobs to reserve and run
|
33
38
|
def work_jobs
|
34
|
-
|
39
|
+
service.run_loop { reserve_and_work_job }
|
35
40
|
end
|
36
41
|
|
37
42
|
# Closes the connection to the Beanstalk queue
|
38
|
-
def
|
39
|
-
|
43
|
+
def close_connection
|
44
|
+
service.close
|
40
45
|
end
|
41
46
|
|
42
47
|
# @yield block A DSL to define jobs for your queue
|
43
48
|
#
|
44
49
|
# @example
|
45
|
-
# Farmer::Runner.
|
50
|
+
# runner = Farmer::Runner.new
|
51
|
+
#
|
52
|
+
# runner.register_handlers do
|
46
53
|
# tube 'sms', proc { |args| puts args }
|
47
54
|
# tube 'mine', Proc.new { |args| puts args }
|
48
55
|
# end
|
49
|
-
def
|
56
|
+
def register_handlers(&block)
|
50
57
|
DSL.execute!(&block)
|
51
58
|
end
|
52
59
|
|
53
60
|
# Looks for jobs to reserve, and applies handlers to them
|
54
|
-
def
|
55
|
-
|
56
|
-
|
61
|
+
def run!
|
62
|
+
prep_tubes
|
63
|
+
work_jobs
|
57
64
|
end
|
58
65
|
end
|
59
66
|
end
|
@@ -1,19 +1,19 @@
|
|
1
1
|
require 'beanstalk-client'
|
2
2
|
require 'multi_json'
|
3
|
-
require 'singleton'
|
4
3
|
|
5
4
|
module BeanstalkFarmer
|
6
5
|
##
|
7
6
|
# Provides an abstraction against our Beanstalk client to buffer us against
|
8
7
|
# changes in their API.
|
9
8
|
#
|
9
|
+
# Set the host and port through the configuration interface.
|
10
|
+
#
|
10
11
|
# @todo Abstract all 3rd party errors
|
11
12
|
# @todo Catch all 3rd party errors, and re-raise our own
|
12
13
|
#
|
13
14
|
# @private
|
14
15
|
class Service
|
15
16
|
include BeanstalkFarmer
|
16
|
-
include Singleton
|
17
17
|
|
18
18
|
DEFAULT_DELAY = 0
|
19
19
|
DEFAULT_PRIORITY = 65536
|
@@ -26,9 +26,9 @@ module BeanstalkFarmer
|
|
26
26
|
# @param [String] host (DEFAULT_HOST) the host name to of your Beanstalk queue
|
27
27
|
#
|
28
28
|
# @param [String] port (DEFAULT_PORT) the port that your Beanstalk queue is on
|
29
|
-
def initialize
|
30
|
-
self.host = host
|
31
|
-
self.port = port
|
29
|
+
def initialize
|
30
|
+
self.host = Config.host
|
31
|
+
self.port = Config.port
|
32
32
|
end
|
33
33
|
|
34
34
|
# @return [String] a formatted URI for a Beanstalk queue
|
@@ -90,6 +90,17 @@ module BeanstalkFarmer
|
|
90
90
|
raise TimedOut, e.message
|
91
91
|
end
|
92
92
|
|
93
|
+
# @see BeanstalkFarmer::Service#reserve
|
94
|
+
def reserve_and_work_job(timeout=nil)
|
95
|
+
job = reserve(timeout)
|
96
|
+
job.work
|
97
|
+
end
|
98
|
+
|
99
|
+
# @yield A block to execute in the run loop
|
100
|
+
def run_loop(&block)
|
101
|
+
loop &block
|
102
|
+
end
|
103
|
+
|
93
104
|
private
|
94
105
|
|
95
106
|
def build_uri(host, port)
|
@@ -1,17 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe BeanstalkFarmer::Job do
|
4
|
+
let(:name) { 'bacon' }
|
5
|
+
|
4
6
|
let(:job) {
|
5
|
-
double('job', body: "[\"
|
7
|
+
double('job', body: "[\"#{name}\",{\"msg\":\"Hello\"}]", name: name, args: { 'msg' => 'Hello' }, ttr: 56, delete: true)
|
6
8
|
}
|
7
9
|
|
10
|
+
let(:delete_handler) { lambda { |args| [:delete] } }
|
11
|
+
|
12
|
+
let(:release_handler) { lambda { |args| [:release, 3, 240] } }
|
13
|
+
|
8
14
|
describe '.new' do
|
9
15
|
it 'sets the job' do
|
10
16
|
described_class.new(job).job.should == job
|
11
17
|
end
|
12
18
|
|
13
19
|
it 'decodes the name of the job' do
|
14
|
-
described_class.new(job).name.should ==
|
20
|
+
described_class.new(job).name.should == name
|
15
21
|
end
|
16
22
|
|
17
23
|
it 'decodes the arguments for the job' do
|
@@ -31,27 +37,109 @@ describe BeanstalkFarmer::Job do
|
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
34
|
-
describe '#
|
35
|
-
let(:
|
40
|
+
describe '#handler' do
|
41
|
+
let(:processor) { double(:processor, call: true) }
|
36
42
|
|
37
43
|
subject { described_class.new(job) }
|
38
44
|
|
39
|
-
before
|
40
|
-
described_class.handler_pool[
|
45
|
+
before do
|
46
|
+
described_class.handler_pool[name] = processor
|
41
47
|
end
|
42
48
|
|
43
|
-
|
44
|
-
|
49
|
+
after do
|
50
|
+
described_class.handler_pool(true)
|
45
51
|
end
|
46
52
|
|
47
|
-
it '
|
48
|
-
|
49
|
-
expect { subject.work }.to raise_error(BeanstalkFarmer::TimedOut)
|
53
|
+
it 'is the handler class used to process the job' do
|
54
|
+
subject.handler.should == processor
|
50
55
|
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#work' do
|
59
|
+
let(:connection) { double('Connection', job_stats: { ttr: 3 }) }
|
60
|
+
|
61
|
+
let(:name) { 'my_job' }
|
62
|
+
|
63
|
+
let(:body) { "[\"#{name}\",{\"msg\":\"Hello\"}]" }
|
64
|
+
|
65
|
+
after(:each) do
|
66
|
+
described_class.handler_pool(:reset)
|
67
|
+
end
|
68
|
+
|
69
|
+
context '(general behaviour)' do
|
70
|
+
let(:handler) { double('handler', call: true) }
|
71
|
+
|
72
|
+
let(:job) { double('job', body: body, ttr: 3, delete: true) }
|
73
|
+
|
74
|
+
subject { described_class.new(job) }
|
75
|
+
|
76
|
+
before do
|
77
|
+
described_class.handler_pool[name] = handler
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'uses the handler to perform some work' do
|
81
|
+
handler.should_receive(:call)
|
82
|
+
subject.work
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'times out if the handler cannot complete in time' do
|
86
|
+
handler.should_receive(:call).and_raise(Timeout::Error)
|
87
|
+
|
88
|
+
expect {
|
89
|
+
subject.work
|
90
|
+
}.to raise_error(BeanstalkFarmer::TimedOut)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'deletes the job by default' do
|
94
|
+
job.should_receive(:delete).once
|
95
|
+
subject.work
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context '(response handling with no arguments)' do
|
100
|
+
let(:action) { :delete }
|
101
|
+
|
102
|
+
let(:handler) { lambda { |args| [action] } }
|
103
|
+
|
104
|
+
let(:job_id) { 3 }
|
105
|
+
|
106
|
+
let(:job) { Beanstalk::Job.new(connection, job_id, body) }
|
107
|
+
|
108
|
+
subject { described_class.new(job) }
|
109
|
+
|
110
|
+
before do
|
111
|
+
described_class.handler_pool[name] = handler
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'calls the specified action' do
|
115
|
+
connection.should_receive(:delete).with(job_id)
|
116
|
+
subject.work
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'response handling with arguments' do
|
121
|
+
let(:action) { :release }
|
122
|
+
|
123
|
+
let(:new_priority) { 3 }
|
124
|
+
|
125
|
+
let(:new_delay) { 240 }
|
126
|
+
|
127
|
+
let(:handler) { lambda { |args| [action, new_priority, new_delay] } }
|
128
|
+
|
129
|
+
let(:job_id) { 1 }
|
130
|
+
|
131
|
+
let(:job) { Beanstalk::Job.new(connection, job_id, body) }
|
132
|
+
|
133
|
+
subject { described_class.new(job) }
|
134
|
+
|
135
|
+
before do
|
136
|
+
described_class.handler_pool[name] = handler
|
137
|
+
end
|
51
138
|
|
52
|
-
|
53
|
-
|
54
|
-
|
139
|
+
it 'reserves the job with appropriate arguments' do
|
140
|
+
connection.should_receive(action).with(job_id, new_priority, new_delay)
|
141
|
+
subject.work
|
142
|
+
end
|
55
143
|
end
|
56
144
|
end
|
57
145
|
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe BeanstalkFarmer::Runner do
|
4
|
-
subject { described_class.
|
5
|
-
|
6
|
-
it 'is a singleton' do
|
7
|
-
described_class.included_modules.should include(Singleton)
|
8
|
-
end
|
4
|
+
subject { described_class.new }
|
9
5
|
|
10
6
|
its(:service) { should be_a_kind_of(BeanstalkFarmer::Service) }
|
11
7
|
|
@@ -24,24 +20,15 @@ describe BeanstalkFarmer::Runner do
|
|
24
20
|
end
|
25
21
|
|
26
22
|
describe '#reserve_and_work_job' do
|
27
|
-
let(:
|
28
|
-
|
29
|
-
before(:each) do
|
30
|
-
subject.stub_chain(:service, :reserve) { job }
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'reserves a job' do
|
34
|
-
subject.service.should_receive(:reserve) { job }
|
35
|
-
subject.reserve_and_work_job
|
36
|
-
end
|
23
|
+
let(:timeout) { 45 }
|
37
24
|
|
38
|
-
it '
|
39
|
-
|
40
|
-
subject.reserve_and_work_job
|
25
|
+
it 'tells the service to reserve and work a job' do
|
26
|
+
subject.service.should_receive(:reserve_and_work_job).with(timeout)
|
27
|
+
subject.reserve_and_work_job(timeout)
|
41
28
|
end
|
42
29
|
end
|
43
30
|
|
44
|
-
describe '
|
31
|
+
describe '#run!' do
|
45
32
|
before(:each) do
|
46
33
|
subject.stub(:prep_tubes)
|
47
34
|
subject.stub(:work_jobs)
|
@@ -49,19 +36,19 @@ describe BeanstalkFarmer::Runner do
|
|
49
36
|
|
50
37
|
it 'prepares tubes for watching' do
|
51
38
|
subject.should_receive(:prep_tubes)
|
52
|
-
|
39
|
+
subject.run!
|
53
40
|
end
|
54
41
|
|
55
42
|
it 'works jobs' do
|
56
43
|
subject.should_receive(:work_jobs)
|
57
|
-
|
44
|
+
subject.run!
|
58
45
|
end
|
59
46
|
end
|
60
47
|
|
61
|
-
describe '
|
48
|
+
describe '#close_connection' do
|
62
49
|
it 'closes the connection to the service' do
|
63
50
|
subject.service.should_receive(:close)
|
64
|
-
|
51
|
+
subject.close_connection
|
65
52
|
end
|
66
53
|
end
|
67
54
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe BeanstalkFarmer::Service, :beanstalk_required do
|
4
|
-
subject { described_class.
|
4
|
+
subject { described_class.new }
|
5
5
|
|
6
6
|
its(:host) { should == BeanstalkFarmer::Config.host }
|
7
7
|
|
@@ -14,14 +14,25 @@ describe BeanstalkFarmer::Service, :beanstalk_required do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
describe '#connection' do
|
17
|
-
|
18
|
-
|
17
|
+
context 'when successful' do
|
18
|
+
after(:each) do
|
19
|
+
subject.close
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'establishes a connection to Beanstalk' do
|
23
|
+
expect {
|
24
|
+
subject.connection.use 'fake.tube'
|
25
|
+
}.to_not raise_error(BeanstalkFarmer::NotConnectedError)
|
26
|
+
end
|
19
27
|
end
|
20
28
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
29
|
+
context 'when failing' do
|
30
|
+
it 'raises an exception if a connection cannot be established' do
|
31
|
+
Beanstalk::Pool.stub(:new).and_raise(Beanstalk::NotConnected)
|
32
|
+
expect {
|
33
|
+
subject.connection
|
34
|
+
}.to raise_error(BeanstalkFarmer::NotConnectedError)
|
35
|
+
end
|
25
36
|
end
|
26
37
|
end
|
27
38
|
|
@@ -89,4 +100,27 @@ describe BeanstalkFarmer::Service, :beanstalk_required do
|
|
89
100
|
}.to raise_error(BeanstalkFarmer::TimedOut)
|
90
101
|
end
|
91
102
|
end
|
103
|
+
|
104
|
+
describe '#reserve_and_work_job' do
|
105
|
+
let(:job) { double(work: true) }
|
106
|
+
|
107
|
+
before(:each) do
|
108
|
+
subject.stub(:reserve) { job }
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'reserves a job' do
|
112
|
+
subject.should_receive(:reserve) { job }
|
113
|
+
subject.reserve_and_work_job
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'passes an optional timeout to the reserved job' do
|
117
|
+
subject.should_receive(:reserve).with(30) { job }
|
118
|
+
subject.reserve_and_work_job(30)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'works the reserved job' do
|
122
|
+
job.should_receive(:work)
|
123
|
+
subject.reserve_and_work_job
|
124
|
+
end
|
125
|
+
end
|
92
126
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ReleaseWorker
|
4
|
+
LIMIT = 2
|
5
|
+
|
6
|
+
@@count = 0
|
7
|
+
|
8
|
+
def self.call(args)
|
9
|
+
if @@count < LIMIT
|
10
|
+
$stderr << "Count: #{@@count}"
|
11
|
+
@@count += 1
|
12
|
+
[:release]
|
13
|
+
else
|
14
|
+
$stderr << args
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end unless defined?(ReleaseWorker)
|
18
|
+
|
19
|
+
describe 'Workers do work', :beanstalk_required do
|
20
|
+
let!(:service) { BeanstalkFarmer::Service.new }
|
21
|
+
|
22
|
+
let!(:runner) { BeanstalkFarmer::Runner.new }
|
23
|
+
|
24
|
+
let(:final_message) { 'Hello. Finally done.' }
|
25
|
+
|
26
|
+
before(:each) do
|
27
|
+
@old_stderr = $stderr
|
28
|
+
@capture = StringIO.new
|
29
|
+
$stderr = @capture
|
30
|
+
|
31
|
+
runner.register_handlers do
|
32
|
+
tube 'echo.release', ReleaseWorker
|
33
|
+
end
|
34
|
+
|
35
|
+
runner.prep_tubes
|
36
|
+
service.enqueue 'echo.release', final_message
|
37
|
+
end
|
38
|
+
|
39
|
+
after(:each) do
|
40
|
+
$stderr = @old_stderr
|
41
|
+
@capture = nil
|
42
|
+
service.close
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'does work with special post-job effects' do
|
46
|
+
ReleaseWorker::LIMIT.times do |n|
|
47
|
+
runner.reserve_and_work_job
|
48
|
+
|
49
|
+
if n < ReleaseWorker::LIMIT
|
50
|
+
@capture.string.should == "Count: #{n}"
|
51
|
+
@capture.rewind
|
52
|
+
else
|
53
|
+
@capture.string.should == final_message
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -7,59 +7,59 @@ class ClassWorker
|
|
7
7
|
end unless defined?(ClassWorker)
|
8
8
|
|
9
9
|
describe 'Workers do work', :beanstalk_required do
|
10
|
+
let!(:service) { BeanstalkFarmer::Service.new }
|
11
|
+
|
12
|
+
let!(:runner) { BeanstalkFarmer::Runner.new }
|
13
|
+
|
10
14
|
before(:each) do
|
11
15
|
@old_stderr = $stderr
|
12
16
|
@capture = StringIO.new
|
13
17
|
$stderr = @capture
|
14
18
|
|
15
|
-
|
19
|
+
runner.register_handlers do
|
16
20
|
tube 'echo.small_proc', proc { |args| $stderr << args }
|
17
21
|
tube 'echo.big_proc', Proc.new { |args| $stderr << args }
|
18
22
|
tube 'echo.class', ClassWorker
|
19
23
|
tube 'echo.block', do |args| $stderr << args; end
|
20
24
|
end
|
21
25
|
|
22
|
-
|
26
|
+
runner.prep_tubes
|
23
27
|
end
|
24
28
|
|
25
29
|
after(:each) do
|
26
30
|
$stderr = @old_stderr
|
27
31
|
@capture = nil
|
28
|
-
|
32
|
+
service.close
|
29
33
|
end
|
30
34
|
|
31
35
|
it 'performs enqueued work with small procs' do
|
32
36
|
message = 'Hello, proc'
|
33
|
-
|
34
|
-
|
35
|
-
BeanstalkFarmer::Runner.instance.reserve_and_work_job
|
37
|
+
service.enqueue 'echo.small_proc', message
|
38
|
+
runner.reserve_and_work_job
|
36
39
|
|
37
40
|
@capture.string.should == message
|
38
41
|
end
|
39
42
|
|
40
43
|
it 'performs enqueued work with blocks' do
|
41
44
|
message = 'Hello, block'
|
42
|
-
|
43
|
-
|
44
|
-
BeanstalkFarmer::Runner.instance.reserve_and_work_job
|
45
|
+
service.enqueue 'echo.block', message
|
46
|
+
runner.reserve_and_work_job
|
45
47
|
|
46
48
|
@capture.string.should == message
|
47
49
|
end
|
48
50
|
|
49
51
|
it 'performs enqueued work with big procs' do
|
50
52
|
message = 'Hello, big Proc'
|
51
|
-
|
52
|
-
|
53
|
-
BeanstalkFarmer::Runner.instance.reserve_and_work_job
|
53
|
+
service.enqueue 'echo.big_proc', message
|
54
|
+
runner.reserve_and_work_job
|
54
55
|
|
55
56
|
@capture.string.should == message
|
56
57
|
end
|
57
58
|
|
58
59
|
it 'performs enqueued work with class' do
|
59
60
|
message = 'Hello, Class'
|
60
|
-
|
61
|
-
|
62
|
-
BeanstalkFarmer::Runner.instance.reserve_and_work_job
|
61
|
+
service.enqueue 'echo.class', message
|
62
|
+
runner.reserve_and_work_job
|
63
63
|
|
64
64
|
@capture.string.should == message
|
65
65
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: beanstalk_farmer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.3.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- James Herdamn
|
@@ -10,10 +10,11 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-07-
|
13
|
+
date: 2011-07-28 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: beanstalk-client
|
17
|
+
prerelease: false
|
17
18
|
requirement: &id001 !ruby/object:Gem::Requirement
|
18
19
|
none: false
|
19
20
|
requirements:
|
@@ -21,10 +22,10 @@ dependencies:
|
|
21
22
|
- !ruby/object:Gem::Version
|
22
23
|
version: 1.1.0
|
23
24
|
type: :runtime
|
24
|
-
prerelease: false
|
25
25
|
version_requirements: *id001
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: multi_json
|
28
|
+
prerelease: false
|
28
29
|
requirement: &id002 !ruby/object:Gem::Requirement
|
29
30
|
none: false
|
30
31
|
requirements:
|
@@ -32,10 +33,10 @@ dependencies:
|
|
32
33
|
- !ruby/object:Gem::Version
|
33
34
|
version: 1.0.2
|
34
35
|
type: :runtime
|
35
|
-
prerelease: false
|
36
36
|
version_requirements: *id002
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: rspec
|
39
|
+
prerelease: false
|
39
40
|
requirement: &id003 !ruby/object:Gem::Requirement
|
40
41
|
none: false
|
41
42
|
requirements:
|
@@ -43,10 +44,10 @@ dependencies:
|
|
43
44
|
- !ruby/object:Gem::Version
|
44
45
|
version: "2.6"
|
45
46
|
type: :development
|
46
|
-
prerelease: false
|
47
47
|
version_requirements: *id003
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: rake
|
50
|
+
prerelease: false
|
50
51
|
requirement: &id004 !ruby/object:Gem::Requirement
|
51
52
|
none: false
|
52
53
|
requirements:
|
@@ -54,10 +55,10 @@ dependencies:
|
|
54
55
|
- !ruby/object:Gem::Version
|
55
56
|
version: 0.9.0
|
56
57
|
type: :development
|
57
|
-
prerelease: false
|
58
58
|
version_requirements: *id004
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: simplecov
|
61
|
+
prerelease: false
|
61
62
|
requirement: &id005 !ruby/object:Gem::Requirement
|
62
63
|
none: false
|
63
64
|
requirements:
|
@@ -65,7 +66,6 @@ dependencies:
|
|
65
66
|
- !ruby/object:Gem::Version
|
66
67
|
version: 0.4.2
|
67
68
|
type: :development
|
68
|
-
prerelease: false
|
69
69
|
version_requirements: *id005
|
70
70
|
description: Farmer is a nice little kit to manage a Beanstalk job queue
|
71
71
|
email:
|
@@ -94,6 +94,7 @@ files:
|
|
94
94
|
- spec/beanstalk_farmer/runner_spec.rb
|
95
95
|
- spec/beanstalk_farmer/service_spec.rb
|
96
96
|
- spec/beastalk_farmer_spec.rb
|
97
|
+
- spec/integration/special_worker_spec.rb
|
97
98
|
- spec/integration/working_spec.rb
|
98
99
|
- spec/spec_helper.rb
|
99
100
|
- spec/support/have_tube_named.rb
|
@@ -110,18 +111,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
111
|
requirements:
|
111
112
|
- - ">="
|
112
113
|
- !ruby/object:Gem::Version
|
113
|
-
hash: -1883747192443942397
|
114
|
-
segments:
|
115
|
-
- 0
|
116
114
|
version: "0"
|
117
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
116
|
none: false
|
119
117
|
requirements:
|
120
118
|
- - ">="
|
121
119
|
- !ruby/object:Gem::Version
|
122
|
-
hash: -1883747192443942397
|
123
|
-
segments:
|
124
|
-
- 0
|
125
120
|
version: "0"
|
126
121
|
requirements: []
|
127
122
|
|
@@ -137,6 +132,7 @@ test_files:
|
|
137
132
|
- spec/beanstalk_farmer/runner_spec.rb
|
138
133
|
- spec/beanstalk_farmer/service_spec.rb
|
139
134
|
- spec/beastalk_farmer_spec.rb
|
135
|
+
- spec/integration/special_worker_spec.rb
|
140
136
|
- spec/integration/working_spec.rb
|
141
137
|
- spec/spec_helper.rb
|
142
138
|
- spec/support/have_tube_named.rb
|