beanstalk_farmer 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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
- # Stalker, the inspiration for this project, subtracted 1 from the job's
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
- logger.error "JOB (#{name}) out of time"
30
- raise TimedOut, "#{name} could not finish in #{job.ttr} seconds"
27
+ handle_timeout!
31
28
  ensure
32
- job.delete
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.instance
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
- job = service.reserve(timeout)
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
- loop { reserve_and_work_job }
39
+ service.run_loop { reserve_and_work_job }
35
40
  end
36
41
 
37
42
  # Closes the connection to the Beanstalk queue
38
- def self.close_connection
39
- instance.service.close
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.register_handlers do
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 self.register_handlers(&block)
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 self.run!
55
- instance.prep_tubes
56
- instance.work_jobs
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(host=Config.host, port=Config.port)
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,3 +1,3 @@
1
1
  module BeanstalkFarmer
2
- VERSION = "0.2.2"
2
+ VERSION = '0.3.0'
3
3
  end
@@ -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: "[\"bacon\",{\"msg\":\"Hello\"}]", name: 'bacon', args: { 'msg' => 'Hello' }, ttr: 56, delete: true)
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 == job.name
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 '#work' do
35
- let(:handler) { proc { |args| args } }
40
+ describe '#handler' do
41
+ let(:processor) { double(:processor, call: true) }
36
42
 
37
43
  subject { described_class.new(job) }
38
44
 
39
- before(:each) do
40
- described_class.handler_pool[job.name] = handler
45
+ before do
46
+ described_class.handler_pool[name] = processor
41
47
  end
42
48
 
43
- it 'performs some work for the handler' do
44
- subject.work.should == job.args
49
+ after do
50
+ described_class.handler_pool(true)
45
51
  end
46
52
 
47
- it 'times out if the job has run out of time' do
48
- Timeout.should_receive(:timeout).with(job.ttr) { raise Timeout::Error }
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
- it 'deletes the job' do
53
- subject.job.should_receive(:delete)
54
- subject.work
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.instance }
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(:job) { double('Farmer::Job', work: true) }
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 'works the job' do
39
- job.should_receive(:work)
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 '.run!' do
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
- described_class.run!
39
+ subject.run!
53
40
  end
54
41
 
55
42
  it 'works jobs' do
56
43
  subject.should_receive(:work_jobs)
57
- described_class.run!
44
+ subject.run!
58
45
  end
59
46
  end
60
47
 
61
- describe '.close_connection' do
48
+ describe '#close_connection' do
62
49
  it 'closes the connection to the service' do
63
50
  subject.service.should_receive(:close)
64
- described_class.close_connection
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.instance }
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
- after(:each) do
18
- subject.close
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
- it 'establishes a connection to Beanstalk' do
22
- expect {
23
- subject.connection.use 'fake.tube'
24
- }.to_not raise_error(BeanstalkFarmer::NotConnectedError)
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
- BeanstalkFarmer::Runner.register_handlers do
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
- BeanstalkFarmer::Runner.instance.prep_tubes
26
+ runner.prep_tubes
23
27
  end
24
28
 
25
29
  after(:each) do
26
30
  $stderr = @old_stderr
27
31
  @capture = nil
28
- BeanstalkFarmer::Service.instance.close
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
- BeanstalkFarmer::Service.instance.enqueue 'echo.small_proc', message
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
- BeanstalkFarmer::Service.instance.enqueue 'echo.block', message
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
- BeanstalkFarmer::Service.instance.enqueue 'echo.big_proc', message
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
- BeanstalkFarmer::Service.instance.enqueue 'echo.class', message
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
@@ -9,6 +9,7 @@ SimpleCov.start do
9
9
  end
10
10
 
11
11
  require 'beanstalk_farmer'
12
+ require 'beanstalk-client'
12
13
 
13
14
  Dir['./spec/support/**/*.rb'].each { |support_file| require support_file }
14
15
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: beanstalk_farmer
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.2.2
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 00:00:00 Z
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