beanstalk-client 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/{License.txt → LICENSE} +0 -0
- data/README.rdoc +20 -0
- data/Rakefile +36 -4
- data/VERSION +1 -0
- data/lib/beanstalk-client.rb +2 -0
- data/lib/beanstalk-client/connection.rb +48 -6
- data/lib/beanstalk-client/job.rb +24 -8
- data/lib/beanstalk-client/version.rb +1 -3
- data/test/helper.rb +9 -0
- data/test/test_beanstalk-client.rb +7 -12
- metadata +63 -57
- data/History.txt +0 -57
- data/Manifest.txt +0 -27
- data/README.txt +0 -1
- data/config/hoe.rb +0 -72
- data/config/requirements.rb +0 -17
- data/log/debug.log +0 -0
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/script/txt2html +0 -74
- data/setup.rb +0 -1585
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/website.rake +0 -17
- data/test/test_helper.rb +0 -2
- data/website/index.html +0 -145
data/.gitignore
ADDED
data/{License.txt → LICENSE}
RENAMED
File without changes
|
data/README.rdoc
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
= Beanstalk Ruby Client
|
2
|
+
By: Keith Rarick
|
3
|
+
|
4
|
+
Beanstalk is a simple, fast workqueue service. Its interface is generic, but was originally designed for reducing the latency of page views in high-volume web applications by running time-consuming tasks asynchronously.
|
5
|
+
|
6
|
+
For more information see:
|
7
|
+
- http://kr.github.com/beanstalkd/
|
8
|
+
- http://github.com/kr/beanstalkd/blob/master/doc/protocol.txt?raw=true
|
9
|
+
|
10
|
+
= Notes
|
11
|
+
|
12
|
+
== Multiple Threads
|
13
|
+
|
14
|
+
If you want to use this library from multiple concurrent threads, you should synchronize access to the connection. This library does no internal synchronization.
|
15
|
+
|
16
|
+
= Contributors
|
17
|
+
- Isaac Feliu
|
18
|
+
- Peter Kieltyka
|
19
|
+
- Martyn Loughran
|
20
|
+
- Dustin Sallings
|
data/Rakefile
CHANGED
@@ -1,4 +1,36 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "beanstalk-client"
|
8
|
+
gem.summary = "Ruby client for beanstalkd"
|
9
|
+
gem.description = "Ruby client for beanstalkd"
|
10
|
+
gem.email = "kr@xph.us"
|
11
|
+
gem.homepage = "http://github.com/kr/beanstalk-client-ruby"
|
12
|
+
gem.authors = ["Keith Rarick"]
|
13
|
+
end
|
14
|
+
Jeweler::GemcutterTasks.new
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
Rake::TestTask.new(:test) do |test|
|
21
|
+
test.libs << 'lib' << 'test'
|
22
|
+
test.pattern = 'test/**/test_*.rb'
|
23
|
+
test.verbose = true
|
24
|
+
end
|
25
|
+
|
26
|
+
task :default => :test
|
27
|
+
|
28
|
+
require 'rake/rdoctask'
|
29
|
+
Rake::RDocTask.new do |rdoc|
|
30
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
31
|
+
|
32
|
+
rdoc.rdoc_dir = 'doc'
|
33
|
+
rdoc.title = "beanstalk-client #{version}"
|
34
|
+
rdoc.rdoc_files.include('README*')
|
35
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
36
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.1.0
|
data/lib/beanstalk-client.rb
CHANGED
@@ -19,14 +19,14 @@ require 'socket'
|
|
19
19
|
require 'fcntl'
|
20
20
|
require 'yaml'
|
21
21
|
require 'set'
|
22
|
-
require '
|
23
|
-
require 'beanstalk-client/job'
|
22
|
+
require 'thread'
|
24
23
|
|
25
24
|
module Beanstalk
|
26
25
|
class Connection
|
27
26
|
attr_reader :addr
|
28
27
|
|
29
28
|
def initialize(addr, default_tube=nil)
|
29
|
+
@mutex = Mutex.new
|
30
30
|
@waiting = false
|
31
31
|
@addr = addr
|
32
32
|
connect
|
@@ -50,6 +50,10 @@ module Beanstalk
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def put(body, pri=65536, delay=0, ttr=120)
|
53
|
+
pri = pri.to_i
|
54
|
+
delay = delay.to_i
|
55
|
+
ttr = ttr.to_i
|
56
|
+
body = body.to_s # Make sure that body.size gives a useful number
|
53
57
|
interact("put #{pri} #{delay} #{ttr} #{body.size}\r\n#{body}\r\n",
|
54
58
|
%w(INSERTED BURIED))[0].to_i
|
55
59
|
end
|
@@ -76,6 +80,7 @@ module Beanstalk
|
|
76
80
|
|
77
81
|
def reserve(timeout=nil)
|
78
82
|
raise WaitingForJobError if @waiting
|
83
|
+
@mutex.lock
|
79
84
|
if timeout.nil?
|
80
85
|
@socket.write("reserve\r\n")
|
81
86
|
else
|
@@ -93,6 +98,8 @@ module Beanstalk
|
|
93
98
|
end
|
94
99
|
|
95
100
|
Job.new(self, *read_job('RESERVED'))
|
101
|
+
ensure
|
102
|
+
@mutex.unlock
|
96
103
|
end
|
97
104
|
|
98
105
|
def delete(id)
|
@@ -101,6 +108,9 @@ module Beanstalk
|
|
101
108
|
end
|
102
109
|
|
103
110
|
def release(id, pri, delay)
|
111
|
+
id = id.to_i
|
112
|
+
pri = pri.to_i
|
113
|
+
delay = delay.to_i
|
104
114
|
interact("release #{id} #{pri} #{delay}\r\n", %w(RELEASED))
|
105
115
|
:ok
|
106
116
|
end
|
@@ -110,6 +120,15 @@ module Beanstalk
|
|
110
120
|
:ok
|
111
121
|
end
|
112
122
|
|
123
|
+
def touch(id)
|
124
|
+
interact("touch #{id}\r\n", %w(TOUCHED))
|
125
|
+
:ok
|
126
|
+
end
|
127
|
+
|
128
|
+
def kick(n)
|
129
|
+
interact("kick #{n}\r\n", %w(KICKED))[0].to_i
|
130
|
+
end
|
131
|
+
|
113
132
|
def use(tube)
|
114
133
|
return tube if tube == @last_used
|
115
134
|
@last_used = interact("use #{tube}\r\n", %w(USING))[0]
|
@@ -162,10 +181,13 @@ module Beanstalk
|
|
162
181
|
|
163
182
|
def interact(cmd, rfmt)
|
164
183
|
raise WaitingForJobError if @waiting
|
184
|
+
@mutex.lock
|
165
185
|
@socket.write(cmd)
|
166
186
|
return read_yaml('OK') if rfmt == :yaml
|
167
187
|
return found_job if rfmt == :job
|
168
188
|
check_resp(*rfmt)
|
189
|
+
ensure
|
190
|
+
@mutex.unlock
|
169
191
|
end
|
170
192
|
|
171
193
|
def get_resp()
|
@@ -193,7 +215,7 @@ module Beanstalk
|
|
193
215
|
id, bytes = check_resp(word).map{|s| s.to_i}
|
194
216
|
body = read_bytes(bytes)
|
195
217
|
raise 'bad trailer' if read_bytes(2) != "\r\n"
|
196
|
-
[id, body]
|
218
|
+
[id, body, word == 'RESERVED']
|
197
219
|
end
|
198
220
|
|
199
221
|
def read_yaml(word)
|
@@ -233,9 +255,10 @@ module Beanstalk
|
|
233
255
|
@watch_list.each{|tube| @connections[addr].watch(tube)}
|
234
256
|
to_ignore.each{|tube| @connections[addr].ignore(tube)}
|
235
257
|
end
|
258
|
+
rescue Errno::ECONNREFUSED
|
259
|
+
raise NotConnected
|
236
260
|
rescue Exception => ex
|
237
261
|
puts "#{ex.class}: #{ex}"
|
238
|
-
#puts begin ex.fixed_backtrace rescue ex.backtrace end
|
239
262
|
end
|
240
263
|
end
|
241
264
|
@connections.size
|
@@ -249,14 +272,28 @@ module Beanstalk
|
|
249
272
|
@last_conn.addr
|
250
273
|
end
|
251
274
|
|
275
|
+
# Put a job on the queue.
|
276
|
+
#
|
277
|
+
# == Parameters:
|
278
|
+
#
|
279
|
+
# * <tt>body</tt>: the payload of the job (use Beanstalk::Pool#yput / Beanstalk::Job#ybody to automatically serialize your payload with YAML)
|
280
|
+
# * <tt>pri</tt>: priority. Default 65536 (higher numbers are higher priority)
|
281
|
+
# * <tt>delay</tt>: how long to wait until making the job available for reservation
|
282
|
+
# * <tt>ttr</tt>: time in seconds for the job to reappear on the queue (if beanstalk doesn't hear from a consumer within this time, assume the consumer died and make the job available for someone else to process). Default 120 seconds.
|
252
283
|
def put(body, pri=65536, delay=0, ttr=120)
|
253
284
|
send_to_rand_conn(:put, body, pri, delay, ttr)
|
254
285
|
end
|
255
286
|
|
287
|
+
# Like put, but serialize the object with YAML.
|
256
288
|
def yput(obj, pri=65536, delay=0, ttr=120)
|
257
289
|
send_to_rand_conn(:yput, obj, pri, delay, ttr)
|
258
290
|
end
|
259
291
|
|
292
|
+
# Reserve a job from the queue.
|
293
|
+
#
|
294
|
+
# == Parameters
|
295
|
+
#
|
296
|
+
# * <tt>timeout</tt> - Time (in seconds) to wait for a job to be available. If nil, wait indefinitely.
|
260
297
|
def reserve(timeout=nil)
|
261
298
|
send_to_rand_conn(:reserve, timeout)
|
262
299
|
end
|
@@ -306,9 +343,12 @@ module Beanstalk
|
|
306
343
|
end
|
307
344
|
|
308
345
|
def remove(conn)
|
309
|
-
@connections.delete(conn.addr)
|
346
|
+
connection = @connections.delete(conn.addr)
|
347
|
+
connection.close if connection
|
348
|
+
connection
|
310
349
|
end
|
311
350
|
|
351
|
+
# Close all open connections for this pool
|
312
352
|
def close
|
313
353
|
while @connections.size > 0
|
314
354
|
addr = @connections.keys.last
|
@@ -339,7 +379,9 @@ module Beanstalk
|
|
339
379
|
def call_wrap(c, *args)
|
340
380
|
self.last_conn = c
|
341
381
|
c.send(*args)
|
342
|
-
rescue
|
382
|
+
rescue UnexpectedResponse => ex
|
383
|
+
raise ex
|
384
|
+
rescue EOFError, Errno::ECONNRESET, Errno::EPIPE => ex
|
343
385
|
self.remove(c)
|
344
386
|
raise ex
|
345
387
|
end
|
data/lib/beanstalk-client/job.rb
CHANGED
@@ -36,28 +36,42 @@ class Beanstalk::Job
|
|
36
36
|
(@ybody ||= [begin YAML.load(body) rescue nil end])[0]
|
37
37
|
end
|
38
38
|
|
39
|
-
def initialize(conn, id, body)
|
39
|
+
def initialize(conn, id, body, reserved=true)
|
40
40
|
@conn = conn
|
41
41
|
@id = id
|
42
42
|
@body = body
|
43
|
-
@
|
43
|
+
@reserved = reserved
|
44
44
|
end
|
45
45
|
|
46
|
+
# Deletes the job from the queue
|
46
47
|
def delete()
|
47
|
-
|
48
|
-
@
|
48
|
+
return if !@reserved
|
49
|
+
@conn.delete(id)
|
50
|
+
@reserved = false
|
49
51
|
end
|
50
52
|
|
53
|
+
|
51
54
|
def put_back(pri=self.pri, delay=0, ttr=self.ttr)
|
52
55
|
@conn.put(body, pri, delay, ttr)
|
53
56
|
end
|
54
57
|
|
55
|
-
|
56
|
-
|
58
|
+
# Releases the job back to the queue so another consumer can get it (call this if the job failed and want it to be tried again)
|
59
|
+
def release(newpri=nil, delay=0)
|
60
|
+
return if !@reserved
|
61
|
+
@conn.release(id, newpri || pri, delay)
|
62
|
+
@reserved = false
|
63
|
+
end
|
64
|
+
|
65
|
+
def bury(newpri=nil)
|
66
|
+
return if !@reserved
|
67
|
+
@conn.bury(id, newpri || pri)
|
68
|
+
@reserved = false
|
57
69
|
end
|
58
70
|
|
59
|
-
|
60
|
-
|
71
|
+
# Ping beanstalkd to to tell it you're alive and processing. If beanstalkd doesn't hear from you for more than the ttr seconds (specified by the put command), then it assumes the consumer died and reinserts the job back into the queue for another to process.
|
72
|
+
def touch
|
73
|
+
return if !@reserved
|
74
|
+
@conn.touch(id)
|
61
75
|
end
|
62
76
|
|
63
77
|
def stats()
|
@@ -65,6 +79,8 @@ class Beanstalk::Job
|
|
65
79
|
end
|
66
80
|
|
67
81
|
def timeouts() stats['timeouts'] end
|
82
|
+
|
83
|
+
# Time left (in seconds) that beanstalk has to process the job. When this time expires, beanstalkd automatically reinserts the job in the queue. See the ttr parameter for Beanstalk::Pool#put
|
68
84
|
def time_left() stats['time-left'] end
|
69
85
|
def age() stats['age'] end
|
70
86
|
def state() stats['state'] end
|
data/test/helper.rb
ADDED
@@ -1,12 +1,7 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def test_truth
|
10
|
-
assert true
|
11
|
-
end
|
12
|
-
end
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestBeanstalkClient < Test::Unit::TestCase
|
4
|
+
def test_truth
|
5
|
+
assert true
|
6
|
+
end
|
7
|
+
end
|
metadata
CHANGED
@@ -1,78 +1,84 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.4
|
3
|
-
specification_version: 1
|
4
2
|
name: beanstalk-client
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
-
|
11
|
-
|
12
|
-
|
13
|
-
rubyforge_project: beanstalk
|
14
|
-
description: Ruby client library for the Beanstalk protocol
|
15
|
-
autorequire:
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: true
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
25
11
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message:
|
29
12
|
authors:
|
30
13
|
- Keith Rarick
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-20 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Ruby client for beanstalkd
|
23
|
+
email: kr@xph.us
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- LICENSE
|
30
|
+
- README.rdoc
|
31
31
|
files:
|
32
|
-
-
|
33
|
-
-
|
34
|
-
-
|
35
|
-
- README.txt
|
32
|
+
- .gitignore
|
33
|
+
- LICENSE
|
34
|
+
- README.rdoc
|
36
35
|
- Rakefile
|
37
|
-
-
|
38
|
-
- config/requirements.rb
|
36
|
+
- VERSION
|
39
37
|
- lib/beanstalk-client.rb
|
40
38
|
- lib/beanstalk-client/connection.rb
|
41
39
|
- lib/beanstalk-client/errors.rb
|
42
40
|
- lib/beanstalk-client/job.rb
|
43
41
|
- lib/beanstalk-client/version.rb
|
44
|
-
-
|
45
|
-
- script/destroy
|
46
|
-
- script/generate
|
47
|
-
- script/txt2html
|
48
|
-
- setup.rb
|
49
|
-
- tasks/deployment.rake
|
50
|
-
- tasks/environment.rake
|
51
|
-
- tasks/website.rake
|
42
|
+
- test/helper.rb
|
52
43
|
- test/test_beanstalk-client.rb
|
53
|
-
- test/test_helper.rb
|
54
|
-
- website/index.html
|
55
44
|
- website/index.txt
|
56
45
|
- website/javascripts/rounded_corners_lite.inc.js
|
57
46
|
- website/stylesheets/screen.css
|
58
47
|
- website/template.rhtml
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
rdoc_options:
|
63
|
-
- --main
|
64
|
-
- README.txt
|
65
|
-
extra_rdoc_files:
|
66
|
-
- History.txt
|
67
|
-
- License.txt
|
68
|
-
- Manifest.txt
|
69
|
-
- README.txt
|
70
|
-
- website/index.txt
|
71
|
-
executables: []
|
72
|
-
|
73
|
-
extensions: []
|
48
|
+
has_rdoc: true
|
49
|
+
homepage: http://github.com/kr/beanstalk-client-ruby
|
50
|
+
licenses: []
|
74
51
|
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options:
|
54
|
+
- --charset=UTF-8
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 3
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
75
|
requirements: []
|
76
76
|
|
77
|
-
|
78
|
-
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 1.3.7
|
79
|
+
signing_key:
|
80
|
+
specification_version: 3
|
81
|
+
summary: Ruby client for beanstalkd
|
82
|
+
test_files:
|
83
|
+
- test/helper.rb
|
84
|
+
- test/test_beanstalk-client.rb
|