em-beanstalk 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -13,12 +13,14 @@ any of the commands that come after the reserve until the reserve completes.
13
13
  This is a bit of a gotcha when sending a series of reserve, delete, etc and there
14
14
  are no available jobs.
15
15
 
16
- = Dependencies
17
- - EventMachine
18
- - RSpec (to run the tests)
19
- - EM::Spec
16
+ == Dependencies
17
+ - eventmachine
20
18
 
21
- = Examples
19
+ === For testing
20
+ - rspec
21
+ - em-spec
22
+
23
+ == Examples
22
24
  EM.run {
23
25
  jack = EM::Beanstalk.new
24
26
 
@@ -40,27 +42,40 @@ are no available jobs.
40
42
  jack.list(:tubes) { |tubes| puts "There are #{tubes.length} tubes defined" }
41
43
  }
42
44
 
45
+ If you need custom error handling, you can chain the error event handler
43
46
 
44
- EM::Beanstalk#each_job is useful for scenarios where the client is a job worker
45
- and intended to process jobs continuously as they become available. Once
46
- the queue is empty, the client will block and wait for a new job.
47
+ == Examples
48
+ EM.run {
49
+ jack = EM::Beanstalk.new
47
50
 
48
- If multiple workers connect to the queue Beanstalkd will round-robin between
49
- the workers.
50
- EM.run {
51
- jack = EM::Beanstalk.new
51
+ jack.delete(job_id) {
52
+ puts "deleted job!"
53
+ }.error {|message|
54
+ puts "I couldn't delete the job because of #{message}"
55
+ }
56
+ }
52
57
 
53
- jack.each_job do |job|
54
- puts "Got job ##{job.id}: #{job}"
58
+ EM::Beanstalk#each_job is useful for scenarios where the client is a job worker
59
+ and intended to process jobs continuously as they become available. Once
60
+ the queue is empty, the client will block and wait for a new job.
55
61
 
56
- if process(job)
57
- jack.delete(job) { puts "*Deleted #{job}*" }
58
- else
59
- # something went horribly wrong!
60
- end
61
- end
62
+ If multiple workers connect to the queue Beanstalkd will round-robin between
63
+ the workers.
64
+
65
+ EM.run {
66
+ jack = EM::Beanstalk.new
62
67
 
63
- def process(job)
64
- # Some kind of job processing
68
+ jack.each_job do |job|
69
+ puts "Got job ##{job.id}: #{job}"
70
+
71
+ if process(job)
72
+ jack.delete(job) { puts "*Deleted #{job}*" }
73
+ else
74
+ # something went horribly wrong!
65
75
  end
66
- }
76
+ end
77
+
78
+ def process(job)
79
+ # Some kind of job processing
80
+ end
81
+ }
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
data/lib/em-beanstalk.rb CHANGED
@@ -4,6 +4,7 @@ require 'yaml'
4
4
  $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
5
5
 
6
6
  require 'em-beanstalk/job'
7
+ require 'em-beanstalk/defer'
7
8
  require 'em-beanstalk/connection'
8
9
 
9
10
  module EM
@@ -12,23 +13,26 @@ module EM
12
13
  Disconnected = Class.new(RuntimeError)
13
14
  InvalidCommand = Class.new(RuntimeError)
14
15
 
16
+ Body = Struct.new(:body, :data)
17
+
15
18
  module VERSION
16
19
  STRING = File.read(File.join(File.dirname(__FILE__), '..', 'VERSION'))
17
20
  end
18
21
 
19
22
  attr_accessor :host, :port
20
- attr_reader :default_priority, :default_delay, :default_ttr
23
+ attr_reader :default_priority, :default_delay, :default_ttr, :default_error_callback
21
24
 
22
25
  def initialize(opts = nil)
23
- @host = opts && opts[:host] || 'localhost'
24
- @port = opts && opts[:port] || 11300
25
- @tube = opts && opts[:tube]
26
- @retry_count = opts && opts[:retry_count] || 5
27
- @default_priority = opts && opts[:default_priority] || 65536
28
- @default_delay = opts && opts[:default_delay] || 0
29
- @default_ttr = opts && opts[:default_ttr] || 300
30
- @default_timeout = opts && opts[:timeout] || 5
31
-
26
+ @host = opts && opts[:host] || 'localhost'
27
+ @port = opts && opts[:port] || 11300
28
+ @tube = opts && opts[:tube]
29
+ @retry_count = opts && opts[:retry_count] || 5
30
+ @default_priority = opts && opts[:default_priority] || 65536
31
+ @default_delay = opts && opts[:default_delay] || 0
32
+ @default_ttr = opts && opts[:default_ttr] || 300
33
+ @default_timeout = opts && opts[:timeout] || 5
34
+ @default_error_callback = opts && opts[:default_error_callback] || Proc.new{ |error| puts "ERROR: #{error.inspect}" }
35
+
32
36
  @used_tube = 'default'
33
37
  @watched_tubes = [@used_tube]
34
38
 
@@ -125,9 +129,9 @@ module EM
125
129
 
126
130
  def list(type = nil, &block)
127
131
  case(type)
128
- when nil then @conn.send(:'list-tubes')
129
- when :use, :used then @conn.send(:'list-tube-used')
130
- when :watch, :watched then @conn.send(:'list-tubes-watched')
132
+ when :tube, :tubes, nil then @conn.send(:'list-tubes')
133
+ when :use, :used then @conn.send(:'list-tube-used')
134
+ when :watch, :watched then @conn.send(:'list-tubes-watched')
131
135
  else raise EM::Beanstalk::InvalidCommand.new
132
136
  end
133
137
  add_deferrable(&block)
@@ -187,17 +191,8 @@ module EM
187
191
  end
188
192
 
189
193
  def add_deferrable(&block)
190
- df = EM::DefaultDeferrable.new
191
- df.errback do
192
- if @error_callback
193
- @error_callback.call
194
- else
195
- puts "ERROR"
196
- end
197
- end
198
-
194
+ df = Defer.new(default_error_callback, &block)
199
195
  @deferrables.push(df)
200
- df.callback(&block) if block
201
196
  df
202
197
  end
203
198
 
@@ -206,88 +201,78 @@ module EM
206
201
  end
207
202
 
208
203
  def received(data)
204
+ puts "received: #{data.inspect}"
209
205
  @data << data
210
-
206
+
211
207
  until @data.empty?
212
- idx = @data.index(/(.*?\r\n)/)
208
+ idx = @data.index(/(.*?)\r\n/)
213
209
  break if idx.nil?
214
210
 
215
211
  first = $1
216
212
 
217
- handled = false
218
- %w(OUT_OF_MEMORY INTERNAL_ERROR DRAINING BAD_FORMAT
219
- UNKNOWN_COMMAND EXPECTED_CRLF JOB_TOO_BIG DEADLINE_SOON
220
- TIMED_OUT NOT_FOUND).each do |cmd|
221
- next unless first =~ /^#{cmd}\r\n/i
222
- df = @deferrables.shift
223
- df.fail(cmd.downcase.to_sym)
224
-
225
- @data = @data[(cmd.length + 2)..-1]
226
- handled = true
227
- break
228
- end
229
- next if handled
230
-
231
213
  case (first)
232
- when /^DELETED\r\n/ then
214
+ when /^DELETED/
233
215
  df = @deferrables.shift
234
216
  df.succeed
235
-
236
- when /^INSERTED\s+(\d+)\r\n/ then
217
+ when /^INSERTED\s+(\d+)/
237
218
  df = @deferrables.shift
238
219
  df.succeed($1.to_i)
239
-
240
- when /^RELEASED\r\n/ then
220
+ when /^RELEASED/
241
221
  df = @deferrables.shift
242
222
  df.succeed
243
-
244
- when /^BURIED\s+(\d+)\r\n/ then
223
+ when /^BURIED\s+(\d+)/
245
224
  df = @deferrables.shift
246
225
  df.fail(:buried, $1.to_i)
247
-
248
- when /^USING\s+(.*)\r\n/ then
226
+ when /^USING\s+(.*)/
249
227
  df = @deferrables.shift
250
228
  df.succeed($1)
251
-
252
- when /^WATCHING\s+(\d+)\r\n/ then
229
+ when /^WATCHING\s+(\d+)/
253
230
  df = @deferrables.shift
254
231
  df.succeed($1.to_i)
255
-
256
- when /^OK\s+(\d+)\r\n/ then
232
+ when /^OK\s+(\d+)/
257
233
  bytes = $1.to_i
258
-
259
- body, @data = extract_body(bytes, @data)
260
- break if body.nil?
261
-
262
- df = @deferrables.shift
263
- df.succeed(YAML.load(body))
264
- next
265
-
266
- when /^RESERVED\s+(\d+)\s+(\d+)\r\n/ then
234
+ if body = extract_body(bytes, @data)
235
+ @data = body.data
236
+ df = @deferrables.shift
237
+ df.succeed(YAML.load(body.body))
238
+ next
239
+ else
240
+ break
241
+ end
242
+ when /^RESERVED\s+(\d+)\s+(\d+)/
267
243
  id = $1.to_i
268
244
  bytes = $2.to_i
269
-
270
- body, @data = extract_body(bytes, @data)
271
- break if body.nil?
272
-
245
+ if body = extract_body(bytes, @data)
246
+ @data = body.data
247
+ df = @deferrables.shift
248
+ job = EM::Beanstalk::Job.new(self, id, body.body)
249
+ df.succeed(job)
250
+ next
251
+ else
252
+ break
253
+ end
254
+ # error state
255
+ when /^(OUT_OF_MEMORY|INTERNAL_ERROR|DRAINING|BAD_FORMAT|UNKNOWN_COMMAND|EXPECTED_CRLF|JOB_TOO_BIG|DEADLINE_SOON|TIMED_OUT|NOT_FOUND)/
273
256
  df = @deferrables.shift
274
- job = EM::Beanstalk::Job.new(self, id, body)
275
- df.succeed(job)
276
- next
257
+ df.fail($1.downcase.to_sym)
258
+ @data = @data[($1.length + 2)..-1]
277
259
  else
278
260
  break
279
261
  end
280
- @data.slice!(0, first.size)
262
+ @data.slice!(0, first.size + 2)
281
263
  end
282
264
  end
283
265
 
284
266
  def extract_body(bytes, data)
285
267
  rem = data[(data.index(/\r\n/) + 2)..-1]
286
- return [nil, data] if rem.length < bytes
287
- body = rem[0..(bytes - 1)]
288
- data = rem[(bytes + 2)..-1]
289
- data = "" if data.nil?
290
- [body, data]
268
+ if rem.length < bytes
269
+ nil
270
+ else
271
+ body = rem[0..(bytes - 1)]
272
+ data = rem[(bytes + 2)..-1]
273
+ data = "" if data.nil?
274
+ Body.new(body, data)
275
+ end
291
276
  end
292
277
  end
293
278
  end
@@ -0,0 +1,15 @@
1
+ module EventMachine
2
+ class Beanstalk
3
+ class Defer < EM::DefaultDeferrable
4
+ def initialize(default_error_callback = nil, &block)
5
+ errback(&default_error_callback) if default_error_callback
6
+ callback(&block) if block
7
+ end
8
+
9
+ def error(&block)
10
+ errback(&block)
11
+ self
12
+ end
13
+ end
14
+ end
15
+ end
@@ -20,6 +20,16 @@ describe EM::Beanstalk, "integration" do
20
20
  end
21
21
  end
22
22
 
23
+ it 'should use errback' do
24
+ conn = EM::Beanstalk.new
25
+ conn.delete(123123) {
26
+ fail
27
+ }.error { |err|
28
+ puts "err! #{err.inspect}"
29
+ done
30
+ }
31
+ end
32
+
23
33
  it 'should send the "use" command' do
24
34
  conn = EM::Beanstalk.new
25
35
  conn.use('my-lovely-tube') do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-beanstalk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-04 00:00:00 -05:00
12
+ date: 2009-12-07 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -37,6 +37,7 @@ files:
37
37
  - VERSION
38
38
  - lib/em-beanstalk.rb
39
39
  - lib/em-beanstalk/connection.rb
40
+ - lib/em-beanstalk/defer.rb
40
41
  - lib/em-beanstalk/job.rb
41
42
  - spec/connection_spec.rb
42
43
  - spec/integration_spec.rb