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.
@@ -0,0 +1,4 @@
1
+ .DS_Store
2
+ pkg
3
+ doc
4
+ *.gemspec
File without changes
@@ -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 'config/requirements'
2
- require 'config/hoe' # setup Hoe + all gem configuration
3
-
4
- Dir['tasks/**/*.rake'].each { |rake| load rake }
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
@@ -24,3 +24,5 @@ module Beanstalk
24
24
  end
25
25
 
26
26
  require 'beanstalk-client/connection'
27
+ require 'beanstalk-client/errors'
28
+ require 'beanstalk-client/job'
@@ -19,14 +19,14 @@ require 'socket'
19
19
  require 'fcntl'
20
20
  require 'yaml'
21
21
  require 'set'
22
- require 'beanstalk-client/errors'
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 EOFError, Errno::ECONNRESET, Errno::EPIPE, UnexpectedResponse => ex
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
@@ -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
- @deleted = false
43
+ @reserved = reserved
44
44
  end
45
45
 
46
+ # Deletes the job from the queue
46
47
  def delete()
47
- @conn.delete(id) if !@deleted
48
- @deleted = true
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
- def release(newpri=pri, delay=0)
56
- @conn.release(id, newpri, delay)
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
- def bury(newpri=pri)
60
- @conn.bury(id, newpri)
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
@@ -1,5 +1,3 @@
1
1
  module Beanstalk #:nodoc:
2
- module VERSION #:nodoc:
3
- STRING = '1.0.2'
4
- end
2
+ VERSION = '1.0.3'
5
3
  end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ require 'beanstalk-client'
7
+
8
+ class Test::Unit::TestCase
9
+ end
@@ -1,12 +1,7 @@
1
- require File.dirname(__FILE__) + '/test_helper.rb'
2
-
3
- require 'beanstalk-client'
4
-
5
- class TestBeanstalk < Test::Unit::TestCase
6
- def setup
7
- end
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
- version: 1.0.2
7
- date: 2008-06-18 00:00:00 -07:00
8
- summary: Ruby client library for the Beanstalk protocol
9
- require_paths:
10
- - lib
11
- email: kr@causes.com
12
- homepage: http://beanstalk.rubyforge.org
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
- - History.txt
33
- - License.txt
34
- - Manifest.txt
35
- - README.txt
32
+ - .gitignore
33
+ - LICENSE
34
+ - README.rdoc
36
35
  - Rakefile
37
- - config/hoe.rb
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
- - log/debug.log
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
- test_files:
60
- - test/test_beanstalk-client.rb
61
- - test/test_helper.rb
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
- dependencies: []
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