em-beanstalk 0.0.4 → 0.0.5
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 +38 -23
- data/VERSION +1 -1
- data/lib/em-beanstalk.rb +59 -74
- data/lib/em-beanstalk/defer.rb +15 -0
- data/spec/integration_spec.rb +10 -0
- metadata +3 -2
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
|
-
|
17
|
-
-
|
18
|
-
- RSpec (to run the tests)
|
19
|
-
- EM::Spec
|
16
|
+
== Dependencies
|
17
|
+
- eventmachine
|
20
18
|
|
21
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
+
== Examples
|
48
|
+
EM.run {
|
49
|
+
jack = EM::Beanstalk.new
|
47
50
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
54
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
-
|
64
|
-
|
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.
|
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
|
24
|
-
@port
|
25
|
-
@tube
|
26
|
-
@retry_count
|
27
|
-
@default_priority
|
28
|
-
@default_delay
|
29
|
-
@default_ttr
|
30
|
-
@default_timeout
|
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
|
130
|
-
when :watch, :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 =
|
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(/(
|
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
|
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
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
when /^RESERVED\s+(\d+)\s+(\d+)
|
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
|
-
|
271
|
-
|
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
|
-
|
275
|
-
|
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
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
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
|
data/spec/integration_spec.rb
CHANGED
@@ -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
|
+
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-
|
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
|