em-jack 0.0.8 → 0.0.9
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 +10 -11
- data/lib/em-jack.rb +1 -1
- data/lib/em-jack/connection.rb +98 -34
- data/lib/em-jack/handlers/buried.rb +11 -2
- data/lib/em-jack/handlers/kicked.rb +20 -0
- data/lib/em-jack/handlers/paused.rb +20 -0
- data/lib/em-jack/handlers/reserved.rb +4 -4
- data/lib/em-jack/handlers/touched.rb +20 -0
- data/lib/em-jack/job.rb +10 -2
- metadata +6 -3
data/README.rdoc
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
= EMJack
|
2
2
|
An attempt to wrap portions of the Beanstalk protocol with EventMachine. Every command
|
3
|
-
will return a deferrable object. That object will succeed or fail depending on the
|
3
|
+
will return a deferrable object. That object will succeed or fail depending on the
|
4
4
|
reply returned from Beanstalk.
|
5
5
|
|
6
|
-
The current, default, errback is to print the error message received.
|
7
|
-
|
8
6
|
One thing to keep in mind. The Beanstalk protocol executes all commands serially.
|
9
7
|
So, if you send a reserve command and there are no jobs Beanstalk _won't_ process
|
10
8
|
any of the commands that come after the reserve until the reserve completes.
|
@@ -19,25 +17,25 @@ are no available jobs.
|
|
19
17
|
= Examples
|
20
18
|
EM.run {
|
21
19
|
jack = EMJack::Connection.new
|
22
|
-
|
20
|
+
|
23
21
|
r = jack.use('mytube')
|
24
22
|
r.callback { |tube| puts "Using #{tube}" }
|
25
|
-
|
23
|
+
|
26
24
|
r = jack.reserve
|
27
25
|
r.callback do |job|
|
28
26
|
puts job.jobid
|
29
27
|
|
30
28
|
r2 = jack.delete(job) { puts "Successfully deleted" }
|
31
29
|
end
|
32
|
-
|
30
|
+
|
33
31
|
r = jack.put("my message", :ttr => 300) { |jobid| puts "put successful #{jobid}" }
|
34
|
-
|
32
|
+
|
35
33
|
r = jack.stats
|
36
34
|
r.callback { |stats| puts "Server up for #{stats['uptime']} seconds" }
|
37
|
-
|
35
|
+
|
38
36
|
r = jack.stats(:tube, "mytube")
|
39
37
|
r.callback { |stats| puts "Total jobs #{stats['total-jobs']}" }
|
40
|
-
|
38
|
+
|
41
39
|
r = jack.list(:used)
|
42
40
|
r.callback { |tubes| puts "There are #{tubes.length} tubes defined" }
|
43
41
|
}
|
@@ -45,12 +43,13 @@ are no available jobs.
|
|
45
43
|
Each of the Jack commands allows an optional block to be provided. If the block is given
|
46
44
|
it will be setup as the callback on the deferrable.
|
47
45
|
|
48
|
-
EMJack#each_job is useful for scenarios where the client is a job worker
|
49
|
-
and intended to process jobs continuously as they become available. Once
|
46
|
+
EMJack#each_job is useful for scenarios where the client is a job worker
|
47
|
+
and intended to process jobs continuously as they become available. Once
|
50
48
|
the queue is empty, the client will block and wait for a new job.
|
51
49
|
|
52
50
|
If multiple workers connect to the queue Beanstalkd will round-robin between
|
53
51
|
the workers.
|
52
|
+
|
54
53
|
EM.run {
|
55
54
|
jack = EMJack::Connection.new
|
56
55
|
|
data/lib/em-jack.rb
CHANGED
data/lib/em-jack/connection.rb
CHANGED
@@ -3,6 +3,8 @@ require 'yaml'
|
|
3
3
|
|
4
4
|
module EMJack
|
5
5
|
class Connection
|
6
|
+
include EM::Deferrable
|
7
|
+
|
6
8
|
RETRY_COUNT = 5
|
7
9
|
|
8
10
|
@@handlers = []
|
@@ -43,14 +45,20 @@ module EMJack
|
|
43
45
|
|
44
46
|
def use(tube, &blk)
|
45
47
|
return if @used_tube == tube
|
46
|
-
|
47
|
-
|
48
|
+
|
49
|
+
callback {
|
50
|
+
@used_tube = tube
|
51
|
+
@conn.send(:use, tube)
|
52
|
+
}
|
53
|
+
|
48
54
|
add_deferrable(&blk)
|
49
55
|
end
|
50
56
|
|
51
57
|
def watch(tube, &blk)
|
52
58
|
return if @watched_tubes.include?(tube)
|
53
|
-
|
59
|
+
|
60
|
+
callback { @conn.send(:watch, tube) }
|
61
|
+
|
54
62
|
df = add_deferrable(&blk)
|
55
63
|
df.callback { @watched_tubes.push(tube) }
|
56
64
|
df
|
@@ -58,44 +66,96 @@ module EMJack
|
|
58
66
|
|
59
67
|
def ignore(tube, &blk)
|
60
68
|
return unless @watched_tubes.include?(tube)
|
61
|
-
|
69
|
+
|
70
|
+
callback { @conn.send(:ignore, tube) }
|
71
|
+
|
62
72
|
df = add_deferrable(&blk)
|
63
73
|
df.callback { @watched_tubes.delete(tube) }
|
64
74
|
df
|
65
75
|
end
|
66
76
|
|
67
77
|
def reserve(timeout = nil, &blk)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
78
|
+
callback {
|
79
|
+
if timeout
|
80
|
+
@conn.send(:'reserve-with-timeout', timeout)
|
81
|
+
else
|
82
|
+
@conn.send(:reserve)
|
83
|
+
end
|
84
|
+
}
|
85
|
+
|
86
|
+
add_deferrable(&blk)
|
87
|
+
end
|
88
|
+
|
89
|
+
def peek(type = nil, &blk)
|
90
|
+
callback {
|
91
|
+
case(type.to_s)
|
92
|
+
when /^\d+$/ then @conn.send(:peek, type)
|
93
|
+
when "ready" then @conn.send(:'peek-ready')
|
94
|
+
when "delayed" then @conn.send(:'peek-delayed')
|
95
|
+
when "buried" then @conn.send(:'peek-buried')
|
96
|
+
else raise EMJack::InvalidCommand.new
|
97
|
+
end
|
98
|
+
}
|
99
|
+
|
73
100
|
add_deferrable(&blk)
|
74
101
|
end
|
75
102
|
|
76
103
|
def stats(type = nil, val = nil, &blk)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
104
|
+
callback {
|
105
|
+
case(type)
|
106
|
+
when nil then @conn.send(:stats)
|
107
|
+
when :tube then @conn.send(:'stats-tube', val)
|
108
|
+
when :job then @conn.send(:'stats-job', val.jobid)
|
109
|
+
else raise EMJack::InvalidCommand.new
|
110
|
+
end
|
111
|
+
}
|
112
|
+
|
83
113
|
add_deferrable(&blk)
|
84
114
|
end
|
85
115
|
|
86
116
|
def list(type = nil, &blk)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
117
|
+
callback {
|
118
|
+
case(type)
|
119
|
+
when nil then @conn.send(:'list-tubes')
|
120
|
+
when :used then @conn.send(:'list-tube-used')
|
121
|
+
when :watched then @conn.send(:'list-tubes-watched')
|
122
|
+
else raise EMJack::InvalidCommand.new
|
123
|
+
end
|
124
|
+
}
|
93
125
|
add_deferrable(&blk)
|
94
126
|
end
|
95
127
|
|
96
128
|
def delete(job, &blk)
|
97
129
|
return if job.nil?
|
98
|
-
|
130
|
+
|
131
|
+
callback { @conn.send(:delete, job.jobid) }
|
132
|
+
|
133
|
+
add_deferrable(&blk)
|
134
|
+
end
|
135
|
+
|
136
|
+
def touch(job, &blk)
|
137
|
+
return if job.nil?
|
138
|
+
|
139
|
+
callback { @conn.send(:touch, job.jobid) }
|
140
|
+
|
141
|
+
add_deferrable(&blk)
|
142
|
+
end
|
143
|
+
|
144
|
+
def bury(job, pri, &blk)
|
145
|
+
callback { @conn.send(:bury, job.jobid, pri) }
|
146
|
+
|
147
|
+
add_deferrable(&blk)
|
148
|
+
end
|
149
|
+
|
150
|
+
def kick(count = 1, &blk)
|
151
|
+
callback { @conn.send(:kick, count) }
|
152
|
+
|
153
|
+
add_deferrable(&blk)
|
154
|
+
end
|
155
|
+
|
156
|
+
def pause(tube, delay, &blk)
|
157
|
+
callback { @conn.send(:'pause-tube', delay) }
|
158
|
+
|
99
159
|
add_deferrable(&blk)
|
100
160
|
end
|
101
161
|
|
@@ -105,12 +165,14 @@ module EMJack
|
|
105
165
|
pri = (opts[:priority] || 65536).to_i
|
106
166
|
delay = (opts[:delay] || 0).to_i
|
107
167
|
|
108
|
-
@conn.send(:release, job.jobid, pri, delay)
|
168
|
+
callback { @conn.send(:release, job.jobid, pri, delay) }
|
169
|
+
|
109
170
|
add_deferrable(&blk)
|
110
171
|
end
|
111
172
|
|
112
173
|
def put(msg, opts = nil, &blk)
|
113
174
|
opts = {} if opts.nil?
|
175
|
+
|
114
176
|
pri = (opts[:priority] || 65536).to_i
|
115
177
|
pri = 65536 if pri< 0
|
116
178
|
pri = 2 ** 32 if pri > (2 ** 32)
|
@@ -123,7 +185,8 @@ module EMJack
|
|
123
185
|
|
124
186
|
m = msg.to_s
|
125
187
|
|
126
|
-
@conn.send_with_data(:put, m, pri, delay, ttr, m.length)
|
188
|
+
callback { @conn.send_with_data(:put, m, pri, delay, ttr, m.length) }
|
189
|
+
|
127
190
|
add_deferrable(&blk)
|
128
191
|
end
|
129
192
|
|
@@ -141,25 +204,26 @@ module EMJack
|
|
141
204
|
|
142
205
|
def connected
|
143
206
|
@retries = 0
|
207
|
+
succeed
|
144
208
|
end
|
145
209
|
|
146
210
|
def disconnected
|
147
|
-
@deferrables.
|
211
|
+
d = @deferrables.dup
|
148
212
|
@deferrables = []
|
149
213
|
|
214
|
+
set_deferred_status(nil)
|
215
|
+
d.each { |df| df.fail(:disconnected) }
|
216
|
+
|
150
217
|
raise EMJack::Disconnected if @retries >= RETRY_COUNT
|
218
|
+
|
151
219
|
@retries += 1
|
152
|
-
EM.add_timer(
|
220
|
+
EM.add_timer(5) { @conn.reconnect(@host, @port) }
|
153
221
|
end
|
154
222
|
|
155
223
|
def add_deferrable(&blk)
|
156
224
|
df = EM::DefaultDeferrable.new
|
157
|
-
|
158
|
-
|
159
|
-
@error_callback.call(err)
|
160
|
-
else
|
161
|
-
puts "ERROR: #{err}"
|
162
|
-
end
|
225
|
+
if @error_callback
|
226
|
+
df.errback { |err| @error_callback.call(err) }
|
163
227
|
end
|
164
228
|
|
165
229
|
df.callback &blk if block_given?
|
@@ -192,7 +256,7 @@ module EMJack
|
|
192
256
|
# if this handler requires us to receive a body make sure we can get
|
193
257
|
# the full length of body. If not, we'll go around and wait for more
|
194
258
|
# data to be received
|
195
|
-
body, @data = extract_body(bytes, @data) unless bytes <= 0
|
259
|
+
body, @data = extract_body!(bytes, @data) unless bytes <= 0
|
196
260
|
break if body.nil? && bytes > 0
|
197
261
|
|
198
262
|
handled = h.handle(df, first, body, self)
|
@@ -210,7 +274,7 @@ module EMJack
|
|
210
274
|
end
|
211
275
|
end
|
212
276
|
|
213
|
-
def extract_body(bytes, data)
|
277
|
+
def extract_body!(bytes, data)
|
214
278
|
rem = data[(data.index(/\r\n/) + 2)..-1]
|
215
279
|
return [nil, data] if rem.length < bytes
|
216
280
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module EMJack
|
2
2
|
module Handler
|
3
3
|
class Buried
|
4
|
-
RESPONSE = /^BURIED\s+(\d+)
|
4
|
+
RESPONSE = /^BURIED(\s+(\d+))?\r\n/
|
5
5
|
|
6
6
|
def self.handles?(response)
|
7
7
|
response =~ RESPONSE
|
@@ -10,7 +10,16 @@ module EMJack
|
|
10
10
|
def self.handle(deferrable, response, body, conn=nil)
|
11
11
|
return false unless response =~ RESPONSE
|
12
12
|
|
13
|
-
|
13
|
+
# if there is an id this is the response of a put command
|
14
|
+
# otherwise, it's either the result of a BURY command or
|
15
|
+
# a release command. I'm assuming the latter 2 are success
|
16
|
+
# and the first is a failure
|
17
|
+
id = $2
|
18
|
+
if id.nil?
|
19
|
+
deferrable.succeed
|
20
|
+
else
|
21
|
+
deferrable.fail(:buried, id.to_i)
|
22
|
+
end
|
14
23
|
true
|
15
24
|
end
|
16
25
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module EMJack
|
2
|
+
module Handler
|
3
|
+
class Kicked
|
4
|
+
RESPONSE = /^KICKED\s+(\d+)\r\n/
|
5
|
+
|
6
|
+
def self.handles?(response)
|
7
|
+
response =~ RESPONSE
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.handle(deferrable, response, body, conn=nil)
|
11
|
+
return false unless response =~ RESPONSE
|
12
|
+
|
13
|
+
deferrable.succeed($1.to_i)
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
EMJack::Connection.register_handler(EMJack::Handler::Kicked)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module EMJack
|
2
|
+
module Handler
|
3
|
+
class Paused
|
4
|
+
RESPONSE = /^PAUSED\r\n/
|
5
|
+
|
6
|
+
def self.handles?(response)
|
7
|
+
response =~ RESPONSE
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.handle(deferrable, response, body, conn=nil)
|
11
|
+
return false unless response =~ RESPONSE
|
12
|
+
|
13
|
+
deferrable.succeed
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
EMJack::Connection.register_handler(EMJack::Handler::Paused)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module EMJack
|
2
2
|
module Handler
|
3
3
|
class Reserved
|
4
|
-
RESPONSE = /^RESERVED\s+(\d+)\s+(\d+)\r\n/
|
4
|
+
RESPONSE = /^(RESERVED|FOUND)\s+(\d+)\s+(\d+)\r\n/
|
5
5
|
|
6
6
|
def self.handles?(response)
|
7
7
|
if response =~ RESPONSE
|
8
|
-
[true, $
|
8
|
+
[true, $3.to_i]
|
9
9
|
else
|
10
10
|
false
|
11
11
|
end
|
@@ -13,8 +13,8 @@ module EMJack
|
|
13
13
|
|
14
14
|
def self.handle(deferrable, response, body, conn)
|
15
15
|
return false unless response =~ RESPONSE
|
16
|
-
id = $
|
17
|
-
bytes = $
|
16
|
+
id = $2.to_i
|
17
|
+
bytes = $3.to_i
|
18
18
|
|
19
19
|
job = EMJack::Job.new(conn, id, body)
|
20
20
|
deferrable.succeed(job)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module EMJack
|
2
|
+
module Handler
|
3
|
+
class Touched
|
4
|
+
RESPONSE = /^TOUCHED\r\n/
|
5
|
+
|
6
|
+
def self.handles?(response)
|
7
|
+
response =~ RESPONSE
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.handle(deferrable, response, body, conn=nil)
|
11
|
+
return false unless response =~ RESPONSE
|
12
|
+
|
13
|
+
deferrable.succeed
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
EMJack::Connection.register_handler(EMJack::Handler::Touched)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/em-jack/job.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
module EMJack
|
2
2
|
class Job
|
3
3
|
attr_accessor :jobid, :body, :ttr, :conn
|
4
|
-
|
4
|
+
|
5
5
|
def initialize(conn, jobid, body)
|
6
6
|
@conn = conn
|
7
7
|
@jobid = jobid.to_i
|
8
8
|
@body = body
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def delete(&blk)
|
12
12
|
@conn.delete(self, &blk)
|
13
13
|
end
|
@@ -20,6 +20,14 @@ module EMJack
|
|
20
20
|
@conn.stats(:job, self, &blk)
|
21
21
|
end
|
22
22
|
|
23
|
+
def touch(&blk)
|
24
|
+
@conn.touch(self, &blk)
|
25
|
+
end
|
26
|
+
|
27
|
+
def bury(delay, &blk)
|
28
|
+
@conn.bury(self, delay, &blk)
|
29
|
+
end
|
30
|
+
|
23
31
|
def to_s
|
24
32
|
"#{@jobid} -- #{body.inspect}"
|
25
33
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 9
|
9
|
+
version: 0.0.9
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- dan sinclair
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-25 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -55,6 +55,9 @@ files:
|
|
55
55
|
- lib/em-jack/handlers/watching.rb
|
56
56
|
- lib/em-jack/handlers/deleted.rb
|
57
57
|
- lib/em-jack/handlers/errors.rb
|
58
|
+
- lib/em-jack/handlers/paused.rb
|
59
|
+
- lib/em-jack/handlers/touched.rb
|
60
|
+
- lib/em-jack/handlers/kicked.rb
|
58
61
|
has_rdoc: true
|
59
62
|
homepage: http://github.com/dj2/em-jack/
|
60
63
|
licenses: []
|