em-jack 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
 
@@ -11,6 +11,6 @@ end
11
11
 
12
12
  module EMJack
13
13
  module VERSION
14
- STRING = '0.0.8'
14
+ STRING = '0.0.9'
15
15
  end
16
16
  end
@@ -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
- @used_tube = tube
47
- @conn.send(:use, tube)
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
- @conn.send(:watch, tube)
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
- @conn.send(:ignore, tube)
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
- if timeout
69
- @conn.send(:'reserve-with-timeout', timeout)
70
- else
71
- @conn.send(:reserve)
72
- end
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
- case(type)
78
- when nil then @conn.send(:stats)
79
- when :tube then @conn.send(:'stats-tube', val)
80
- when :job then @conn.send(:'stats-job', val.jobid)
81
- else raise EMJack::InvalidCommand.new
82
- end
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
- case(type)
88
- when nil then @conn.send(:'list-tubes')
89
- when :used then @conn.send(:'list-tube-used')
90
- when :watched then @conn.send(:'list-tubes-watched')
91
- else raise EMJack::InvalidCommand.new
92
- end
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
- @conn.send(:delete, job.jobid)
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.each { |df| df.fail(:disconnected) }
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(1) { @conn.reconnect(@host, @port) }
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
- df.errback do |err|
158
- if @error_callback
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+)\r\n/
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
- deferrable.fail(:buried, $1.to_i)
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, $2.to_i]
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 = $1.to_i
17
- bytes = $2.to_i
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
@@ -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
- - 8
9
- version: 0.0.8
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-23 00:00:00 -04:00
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: []