beaneater 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # CHANGELOG for Beaneater
2
+
3
+ ## 0.1.2 (Unreleased)
4
+
5
+ ## 0.1.1 (Nov 4 2012)
6
+
7
+ * Add `Jobs#find_all` to fix #10
8
+ * Fixed issue with `tubes-list` by merging results
9
+ * Add `Job#ttr`, `Job#pri`, `Job#delay`
10
+ * Improved yardocs coverage and accuracy
11
+
12
+ ## 0.1.0 (Nov 1 2012)
13
+
14
+ * Initial release!
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Beaneater is the best way to interact with beanstalkd from within Ruby.
4
4
  [Beanstalkd](http://kr.github.com/beanstalkd/) is a simple, fast work queue. Its interface is generic, but was
5
5
  originally designed for reducing the latency of page views in high-volume web applications by
6
- running time-consuming tasks asynchronously. Read the
6
+ running time-consuming tasks asynchronously. Read the [yardocs](http://rdoc.info/github/beanstalkd/beaneater) and/or the
7
7
  [beanstalk protocol](https://github.com/kr/beanstalkd/blob/master/doc/protocol.md) for more details.
8
8
 
9
9
 
@@ -13,32 +13,35 @@ Illya has an excellent blog post
13
13
  [Scalable Work Queues with Beanstalk](http://www.igvita.com/2010/05/20/scalable-work-queues-with-beanstalk/) and
14
14
  Adam Wiggins posted [an excellent comparison](http://adam.heroku.com/past/2010/4/24/beanstalk_a_simple_and_fast_queueing_backend/).
15
15
 
16
- You will quickly see that **beanstalkd** is an underrated but incredible project that is extremely well-suited as a job queue.
17
- Significantly better suited for this task than Redis or a database. Beanstalk is a simple,
18
- and a very fast work queue service rolled into a single binary - it is the memcached of work queues.
19
- Originally built to power the backend for the 'Causes' Facebook app, it is a mature and production ready open source project.
20
- [PostRank](http://www.postrank.com) uses beanstalk to reliably process millions of jobs a day.
16
+ You will find that **beanstalkd** is an underrated but incredibly
17
+ powerful project that is extremely well-suited as a job or messaging queue.
18
+ Significantly better suited for this task than Redis or a traditional RDBMS. Beanstalk is a simple,
19
+ and fast work queue service rolled into a single binary - it is the memcached of work queues.
20
+ Originally built to power the backend for the 'Causes' Facebook app,
21
+ it is a mature and production ready open source project.
22
+ [PostRank](http://www.postrank.com) has used beanstalk to reliably process millions of jobs a day.
21
23
 
22
24
  A single instance of Beanstalk is perfectly capable of handling thousands of jobs a second (or more, depending on your job size)
23
25
  because it is an in-memory, event-driven system. Powered by libevent under the hood,
24
- it requires zero setup (launch and forget, à la memcached), optional log based persistence, an easily parsed ASCII protocol,
25
- and a rich set of tools for job management that go well beyond a simple FIFO work queue.
26
+ it requires zero setup (launch and forget, à la memcached), optional log based persistence,
27
+ an easily parsed ASCII protocol, and a rich set of tools for job management
28
+ that go well beyond a simple FIFO work queue.
26
29
 
27
30
  Beanstalkd supports the following features out of the box:
28
31
 
29
32
  | Feature | Description |
30
33
  | ------- | ------------------------------- |
31
- | **Parallel Queues** | Supports multiple work queues created on demand. |
34
+ | **Parallelized** | Supports multiple work queues created on demand. |
32
35
  | **Reliable** | Beanstalk’s reserve, work, delete cycle ensures reliable processing. |
33
36
  | **Scheduling** | Delay enqueuing jobs by a specified interval to schedule processing later |
34
- | **Fast** | Processes thousands of jobs per second; **significantly** faster than alternatives. |
37
+ | **Fast** | Processes thousands of jobs per second without breaking a sweat. |
35
38
  | **Priorities** | Specify priority so important jobs can be processed quickly. |
36
39
  | **Persistence** | Jobs are stored in memory for speed, but logged to disk for safe keeping. |
37
40
  | **Federation** | Horizontal scalability provided through federation by the client. |
38
41
  | **Error Handling** | Bury any job which causes an error for later debugging and inspection.|
39
42
 
40
- Keep in mind that these features are supported out of the box with beanstalk and require no special code within this gem to support.
41
- In the end, **beanstalk is the ideal job queue** while also being ridiculously easy to install and setup.
43
+ Keep in mind that these features are supported out of the box with beanstalk and requires no special ruby specific logic.
44
+ In the end, **beanstalk is the ideal job queue** and has the added benefit of being easy to setup and configure.
42
45
 
43
46
  ## Installation
44
47
 
@@ -47,7 +50,6 @@ Install beanstalkd:
47
50
  Mac OS
48
51
 
49
52
  ```
50
- brew update
51
53
  brew install beanstalkd
52
54
  beanstalkd -p 11300
53
55
  ```
@@ -74,6 +76,29 @@ gem 'beaneater'
74
76
 
75
77
  and run `bundle install` to install the dependency.
76
78
 
79
+ ## Quick Overview:
80
+
81
+ The concise summary of how to use beaneater:
82
+
83
+ ```ruby
84
+ # Connect to pool
85
+ @beanstalk = Beaneater::Pool.new(['localhost:11300'])
86
+ # Enqueue jobs to tube
87
+ @tube = @beanstalk.tubes["my-tube"]
88
+ @tube.put '{ "key" : "foo" }', :pri => 5
89
+ @tube.put '{ "key" : "bar" }', :delay => 3
90
+ # Process jobs from tube
91
+ while @tube.peek(:ready)
92
+ job = @tube.reserve
93
+ puts "job value is #{job.body["key"]}!"
94
+ job.delete
95
+ end
96
+ # Disconnect the pool
97
+ @beanstalk.close
98
+ ```
99
+
100
+ For a more detailed rundown, check out the __Usage__ section below.
101
+
77
102
  ## Usage
78
103
 
79
104
  ### Connection
@@ -82,6 +107,11 @@ To interact with a beanstalk queue, first establish a connection by providing a
82
107
 
83
108
  ```ruby
84
109
  @beanstalk = Beaneater::Pool.new(['10.0.1.5:11300'])
110
+
111
+ # Or if ENV['BEANSTALKD_URL] == 'localhost:11300,127.0.0.1:11300'
112
+ @beanstalk = Beaneater::Pool.new
113
+ @beanstalk.connections.first # => localhost:11300
114
+ @beanstalk.connections.last # => 127.0.0.1:11300
85
115
  ```
86
116
 
87
117
  You can conversely close and dispose of a pool at any time with:
@@ -277,6 +307,13 @@ inspected using the 'peek' commands. To find and peek at a particular job based
277
307
  # => <Beaneater::Job id=123 body="foo">
278
308
  ```
279
309
 
310
+ You can also `find_all` jobs across all connections:
311
+
312
+ ```ruby
313
+ @beanstalk.jobs.find_all(123)
314
+ # => [<Beaneater::Job id=123 body="foo">, <Beaneater::Job id=123 body="bar">]
315
+ ```
316
+
280
317
  or you can peek at jobs within a tube:
281
318
 
282
319
  ```ruby
@@ -346,6 +383,7 @@ are listed below:
346
383
  | Beaneater::InvalidTubeName | Specified tube name for use or watch is not valid. |
347
384
  | Beaneater::NotFoundError | Specified job or tube could not be found. |
348
385
  | Beaneater::TimedOutError | Job could not be reserved within time specified. |
386
+ | Beaneater::JobNotReserved | Job has not been reserved and action cannot be taken. |
349
387
 
350
388
  There are other exceptions that are less common such as `OutOfMemoryError`, `DrainingError`,
351
389
  `DeadlineSoonError`, `InternalError`, `BadFormatError`, `UnknownCommandError`,
@@ -389,11 +427,15 @@ more details about the stats commands.
389
427
 
390
428
  There are other resources helpful when learning about beanstalk:
391
429
 
430
+ * [Beaneater Yardocs](http://rdoc.info/github/beanstalkd/beaneater)
431
+ * [Beaneater on Rubygems](https://rubygems.org/gems/beaneater)
392
432
  * [Beanstalkd homepage](http://kr.github.com/beanstalkd/)
393
433
  * [beanstalk on github](https://github.com/kr/beanstalkd)
394
434
  * [beanstalk protocol](https://github.com/kr/beanstalkd/blob/master/doc/protocol.md)
435
+ * [Backburner](https://github.com/nesquena/backburner) - Ruby job queue for Rails/Sinatra
395
436
 
396
437
  ## Contributors
397
438
 
398
439
  - [Nico Taing](https://github.com/Nico-Taing) - Creator and co-maintainer
399
- - [Nathan Esquenazi](https://github.com/nesquena) - Contributor and co-maintainer
440
+ - [Nathan Esquenazi](https://github.com/nesquena) - Contributor and co-maintainer
441
+ - [Keith Rarick](https://github.com/kr) - Much code inspired and adapted from beanstalk-client
data/Rakefile CHANGED
@@ -3,6 +3,7 @@ require 'rake/testtask'
3
3
  require 'yard'
4
4
  require 'redcarpet'
5
5
 
6
+ # rake test
6
7
  Rake::TestTask.new do |t|
7
8
  t.libs.push "lib"
8
9
  t.test_files = FileList[File.expand_path('../test/**/*_test.rb', __FILE__)] -
@@ -10,6 +11,13 @@ Rake::TestTask.new do |t|
10
11
  t.verbose = true
11
12
  end
12
13
 
14
+ # rake test:integration
15
+ Rake::TestTask.new("test:integration") do |t|
16
+ t.libs.push "lib"
17
+ t.test_files = FileList[File.expand_path('../test/**/beaneater_test.rb', __FILE__)]
18
+ t.verbose = true
19
+ end
20
+
13
21
  # rake test:full
14
22
  Rake::TestTask.new("test:full") do |t|
15
23
  t.libs.push "lib"
data/TODO CHANGED
@@ -1,2 +1 @@
1
- - Add YARD docs for all classes (see REF file)
2
1
  - Remove connection from pool if it's not responding and be able to add more connections and reattempt later
@@ -1,42 +1,50 @@
1
1
  require 'yaml'
2
2
 
3
3
  module Beaneater
4
- # Represents a connection to beanstalkd server
4
+ # Represents a connection to a beanstalkd instance.
5
5
  class Connection
6
6
 
7
- # @!attribute telnet_connection
8
- # @return [Net::Telnet] returns Telnet connection object
9
7
  # @!attribute address
10
8
  # @return [String] returns Beanstalkd server address
9
+ # @example
10
+ # @conn.address # => "localhost:11300"
11
11
  # @!attribute host
12
12
  # @return [String] returns Beanstalkd server host
13
+ # @example
14
+ # @conn.host # => "localhost"
13
15
  # @!attribute port
14
16
  # @return [Integer] returns Beanstalkd server port
15
- attr_reader :telnet_connection, :address, :host, :port
17
+ # @example
18
+ # @conn.port # => "11300"
19
+ # @!attribute telnet_connection
20
+ # @return [Net::Telnet] returns Telnet connection object
21
+ attr_reader :address, :host, :port, :telnet_connection
16
22
 
17
- # Default port value
23
+ # Default port value for beanstalk connection
18
24
  DEFAULT_PORT = 11300
19
25
 
20
- # Initialize new connection
26
+ # Initializes new connection.
21
27
  #
22
- # @param [String] address beanstalkd address
28
+ # @param [String] address beanstalkd instance address.
23
29
  # @example
24
30
  # Beaneater::Connection.new('localhost')
25
31
  # Beaneater::Connection.new('localhost:11300')
32
+ #
26
33
  def initialize(address)
27
34
  @address = address
28
35
  @telnet_connection = establish_connection
29
36
  @mutex = Mutex.new
30
37
  end
31
38
 
32
- # Send commands to beanstalkd server via telnet_connection
39
+ # Send commands to beanstalkd server via telnet_connection.
33
40
  #
34
41
  # @param [String] command Beanstalkd command
35
- # @param [Hash] options Settings for telnet
42
+ # @param [Hash{Symbol => String,Boolean}] options Settings for telnet
36
43
  # @option options [Boolean] FailEOF raises EOF Exeception
37
- #
44
+ # @return [Array<Hash{String => String, Number}>] Beanstalkd command response
38
45
  # @example
39
- # @beaneater_connection.transmit('bury 123')
46
+ # @conn.transmit('bury 123')
47
+ #
40
48
  def transmit(command, options={}, &block)
41
49
  @mutex.lock
42
50
  if telnet_connection
@@ -49,19 +57,21 @@ module Beaneater
49
57
  @mutex.unlock
50
58
  end
51
59
 
52
- # Close connection with beanstalkd server
60
+ # Close connection with beanstalkd server.
53
61
  #
54
62
  # @example
55
- # @beaneater_connection.close
63
+ # @conn.close
64
+ #
56
65
  def close
57
66
  @telnet_connection.close
58
67
  @telnet_connection = nil
59
68
  end
60
69
 
61
- # Returns string representation of job
70
+ # Returns string representation of job.
62
71
  #
63
72
  # @example
64
- # @beaneater_connection.inspect
73
+ # @conn.inspect
74
+ #
65
75
  def to_s
66
76
  "#<Beaneater::Connection host=#{host.inspect} port=#{port.inspect}>"
67
77
  end
@@ -90,7 +100,7 @@ module Beaneater
90
100
  #
91
101
  # @param [String] cmd Beanstalk command transmitted
92
102
  # @param [String] res Telnet command response
93
- # @return [Hash] Beanstalk command response with `status`, `id`, `body`, and `connection`
103
+ # @return [Array<Hash{String => String, Number}>] Beanstalk response with `status`, `id`, `body`, and `connection`
94
104
  # @raise [Beaneater::UnexpectedResponse] Response from beanstalk command was an error status
95
105
  # @example
96
106
  # parse_response("delete 56", "DELETED 56\nFOO")
@@ -1,5 +1,5 @@
1
1
  module Beaneater
2
- # Raises when the beanstalkd instance cannot be accessed
2
+ # Raises when a beanstalkd instance is no longer accessible.
3
3
  class NotConnected < RuntimeError; end
4
4
  # Raises when the tube name specified is invalid.
5
5
  class InvalidTubeName < RuntimeError; end
@@ -15,13 +15,15 @@ module Beaneater
15
15
 
16
16
  # @!attribute status
17
17
  # @return [String] returns beanstalkd response status
18
+ # @example @ex.status # => "NOT_FOUND"
18
19
  # @!attribute cmd
19
20
  # @return [String] returns beanstalkd request command
21
+ # @example @ex.cmd # => "stats-job 23"
20
22
  attr_reader :status, :cmd
21
23
 
22
24
  # Initialize unexpected response error
23
25
  #
24
- # @param [UnexpectedResponse] status Unexpected response object
26
+ # @param [Beaneater::UnexpectedResponse] status Unexpected response object
25
27
  # @param [String] cmd Beanstalkd request command
26
28
  #
27
29
  # @example
@@ -37,6 +39,7 @@ module Beaneater
37
39
  # @param [String] status Beanstalkd error status
38
40
  # @param [String] cmd Beanstalkd request command
39
41
  #
42
+ # @return [Beaneater::UnexpectedResponse] Exception for the status provided
40
43
  # @example
41
44
  # Beaneater::UnexpectedResponse.new('NOT_FOUND', 'bury 123')
42
45
  #
@@ -1,30 +1,29 @@
1
1
  module Beaneater
2
- # Exception to stop processing jobs
2
+ # Exception to stop processing jobs during a `process!` loop.
3
+ # Simply `raise AbortProcessingError` in any job process handler to stop the processing loop.
3
4
  class AbortProcessingError < RuntimeError; end
4
5
 
5
- # Represents collection of jobs related commands.
6
+ # Represents collection of job-related commands.
6
7
  class Jobs < PoolCommand
7
8
 
8
9
  # @!attribute processors
9
10
  # @return [Array<Proc>] returns Collection of proc to handle beanstalkd jobs
10
11
  attr_reader :processors
11
12
 
12
- # Number of retries to process a job
13
+ # Number of retries to process a job.
13
14
  MAX_RETRIES = 3
14
15
 
15
- # Delay in seconds before to make job ready again
16
+ # Delay in seconds before to make job ready again.
16
17
  RELEASE_DELAY = 1
17
18
 
18
- # Peek (or find) a job across all beanstalkd servers from pool
19
- #
20
- # @param [Integer] id Job id
21
- #
22
- # @raise [Beaneater::NotFoundError] Job not found
19
+ # Peek (or find) first job from beanstalkd pool.
23
20
  #
21
+ # @param [Integer] id Job id to find
22
+ # @return [Beaneater::Job] Job matching given id
24
23
  # @example
24
+ # @beaneater_pool.jobs[123] # => <Beaneater::Job>
25
25
  # @beaneater_pool.jobs.find(123) # => <Beaneater::Job>
26
26
  # @beaneater_pool.jobs.peek(123) # => <Beaneater::Job>
27
- # @beaneater_pool.jobs.find[123] # => <Beaneater::Job>
28
27
  #
29
28
  # @api public
30
29
  def find(id)
@@ -36,13 +35,28 @@ module Beaneater
36
35
  alias_method :peek, :find
37
36
  alias_method :[], :find
38
37
 
39
- # Add processor to handle beanstalkd job
38
+ # Find all jobs with specified id fromm all beanstalkd servers in pool.
39
+ #
40
+ # @param [Integer] id Job id to find
41
+ # @return [Array<Beaneater::Job>] Jobs matching given id
42
+ # @example
43
+ # @beaneater_pool.jobs.find_all(123) # => [<Beaneater::Job>, <Beaneater::Job>]
44
+ #
45
+ # @api public
46
+ def find_all(id)
47
+ res = transmit_to_all("peek #{id}")
48
+ res.compact.map { |r| Job.new(r) }
49
+ rescue Beaneater::NotFoundError => ex
50
+ []
51
+ end
52
+
53
+ # Register a processor to handle beanstalkd job on particular tube.
40
54
  #
41
55
  # @param [String] tube_name Tube name
42
- # @param [Hash] options settings for processor
56
+ # @param [Hash{String=>RuntimeError}] options settings for processor
57
+ # @param [Proc] block Process beanstalkd job
43
58
  # @option options [Integer] max_retries Number of retries to process a job
44
59
  # @option options [Array<RuntimeError>] retry_on Collection of errors to rescue and re-run processor
45
- # @param [Proc] block Process beanstalkd job
46
60
  #
47
61
  # @example
48
62
  # @beanstalk.jobs.register('some-tube', :retry_on => [SomeError]) do |job|
@@ -61,10 +75,10 @@ module Beaneater
61
75
  @processors[tube_name.to_s] = { :block => block, :retry_on => retry_on, :max_retries => max_retries }
62
76
  end
63
77
 
64
- # Watch, reserve, process and delete or bury or release jobs
78
+ # Watch, reserve, process and delete or bury or release jobs.
65
79
  #
66
- # @param [Hash] options Settings for processing
67
- # @option options [Integer] Delay in seconds before to make job ready again
80
+ # @param [Hash{String => Integer}] options Settings for processing
81
+ # @option options [Integer] release_delay Delay in seconds before to make job ready again
68
82
  #
69
83
  # @api public
70
84
  def process!(options={})
@@ -3,19 +3,20 @@ module Beaneater
3
3
  class Job
4
4
 
5
5
  # @!attribute id
6
- # @return [Integer] returns Job id
6
+ # @return [Integer] id for the job.
7
7
  # @!attribute body
8
- # @return [String] returns Job body
8
+ # @return [String] the job's body.
9
9
  # @!attribute connection
10
- # @return [Beaneater::Connection] returns Connection which has retrieved job
10
+ # @return [Beaneater::Connection] connection which has retrieved job.
11
11
  # @!attribute reserved
12
- # @return [Boolean] returns If job is being reserved
12
+ # @return [Boolean] whether the job has been reserved.
13
13
  attr_reader :id, :body, :connection, :reserved
14
14
 
15
15
 
16
- # Initialize new connection
16
+ # Initializes a new job object.
17
+ #
18
+ # @param [Hash{Symbol => String,Number}] res Result from beanstalkd response
17
19
  #
18
- # @param [Hash] res result from beanstalkd response
19
20
  def initialize(res)
20
21
  @id = res[:id]
21
22
  @body = res[:body]
@@ -23,9 +24,9 @@ module Beaneater
23
24
  @reserved = res[:status] == 'RESERVED'
24
25
  end
25
26
 
26
- # Send command to bury job
27
+ # Sends command to bury a reserved job.
27
28
  #
28
- # @param [Hash] options Settings to bury job
29
+ # @param [Hash{Symbol => Integer}] options Settings to bury job
29
30
  # @option options [Integer] pri Assign new priority to job
30
31
  #
31
32
  # @example
@@ -39,12 +40,11 @@ module Beaneater
39
40
  end
40
41
  end
41
42
 
42
- # Send command to release job
43
+ # Sends command to release a job back to ready state.
43
44
  #
44
- # @param [Hash] options Settings to release job
45
+ # @param [Hash{String => Integer}] options Settings to release job
45
46
  # @option options [Integer] pri Assign new priority to job
46
- # @option options [Integer] pri Assign new delay to job
47
- #
47
+ # @option options [Integer] delay Assign new delay to job
48
48
  # @example
49
49
  # @beaneater_connection.jobs.find(123).release(:pri => 10, :delay => 5)
50
50
  #
@@ -56,7 +56,7 @@ module Beaneater
56
56
  end
57
57
  end
58
58
 
59
- # Send command to touch job
59
+ # Sends command to touch job which extends the ttr.
60
60
  #
61
61
  # @example
62
62
  # @beaneater_connection.jobs.find(123).touch
@@ -66,7 +66,7 @@ module Beaneater
66
66
  with_reserved("touch #{id}")
67
67
  end
68
68
 
69
- # Send command to delete job
69
+ # Sends command to delete a job.
70
70
  #
71
71
  # @example
72
72
  # @beaneater_connection.jobs.find(123).delete
@@ -76,7 +76,7 @@ module Beaneater
76
76
  transmit("delete #{id}") { @reserved = false }
77
77
  end
78
78
 
79
- # Send command to kick job
79
+ # Sends command to kick a buried job.
80
80
  #
81
81
  # @example
82
82
  # @beaneater_connection.jobs.find(123).kick
@@ -86,10 +86,12 @@ module Beaneater
86
86
  transmit("kick-job #{id}")
87
87
  end
88
88
 
89
- # Send command to get stats about job
89
+ # Sends command to get stats about job.
90
90
  #
91
+ # @return [Beaneater::StatStruct] struct filled with relevant job stats
91
92
  # @example
92
93
  # @beaneater_connection.jobs.find(123).stats
94
+ # @job.stats.tube # => "some-tube"
93
95
  #
94
96
  # @api public
95
97
  def stats
@@ -97,8 +99,9 @@ module Beaneater
97
99
  StatStruct.from_hash(res[:body])
98
100
  end
99
101
 
100
- # Check if job is being reserved
102
+ # Check if job is currently in a reserved state.
101
103
  #
104
+ # @return [Boolean] Returns true if the job is in a reserved state
102
105
  # @example
103
106
  # @beaneater_connection.jobs.find(123).reserved?
104
107
  #
@@ -107,35 +110,70 @@ module Beaneater
107
110
  @reserved || self.stats.state == "reserved"
108
111
  end
109
112
 
110
- # Check if job exists
113
+ # Check if the job still exists.
111
114
  #
115
+ # @return [Boolean] Returns true if the job still exists
112
116
  # @example
113
117
  # @beaneater_connection.jobs.find(123).exists?
114
118
  #
115
119
  # @api public
116
120
  def exists?
117
- !!self.stats
121
+ !self.stats.nil?
118
122
  rescue Beaneater::NotFoundError
119
123
  false
120
124
  end
121
125
 
122
126
  # Returns the name of the tube this job is in
123
127
  #
128
+ # @return [String] The name of the tube for this job
124
129
  # @example
125
130
  # @beaneater_connection.jobs.find(123).tube
131
+ # # => "some-tube"
126
132
  #
127
- # @api public
128
133
  def tube
129
134
  self.stats && self.stats.tube
130
135
  end
131
136
 
137
+ # Returns the ttr of this job
138
+ #
139
+ # @return [String] The ttr of this job
140
+ # @example
141
+ # @beaneater_connection.jobs.find(123).ttr
142
+ # # => 123
143
+ #
144
+ def ttr
145
+ self.stats && self.stats.ttr
146
+ end
147
+
148
+ # Returns the pri of this job
149
+ #
150
+ # @return [String] The pri of this job
151
+ # @example
152
+ # @beaneater_connection.jobs.find(123).pri
153
+ # # => 1
154
+ #
155
+ def pri
156
+ self.stats && self.stats.pri
157
+ end
158
+
159
+ # Returns the delay of this job
160
+ #
161
+ # @return [String] The delay of this job
162
+ # @example
163
+ # @beaneater_connection.jobs.find(123).delay
164
+ # # => 5
165
+ #
166
+ def delay
167
+ self.stats && self.stats.delay
168
+ end
169
+
132
170
  # Returns string representation of job
133
171
  #
172
+ # @return [String] string representation
134
173
  # @example
135
174
  # @beaneater_connection.jobs.find(123).to_s
136
175
  # @beaneater_connection.jobs.find(123).inspect
137
176
  #
138
- # @api public
139
177
  def to_s
140
178
  "#<Beaneater::Job id=#{id} body=#{body.inspect}>"
141
179
  end
@@ -146,7 +184,7 @@ module Beaneater
146
184
  # Transmit command to beanstalkd instances and fetch response.
147
185
  #
148
186
  # @param [String] cmd Beanstalkd command to send.
149
- # @return [Hash] Beanstalkd response for the command.
187
+ # @return [Hash{Symbol => String,Number}] Beanstalkd response for the command.
150
188
  # @example
151
189
  # transmit('stats')
152
190
  # transmit('stats') { 'success' }
@@ -160,7 +198,7 @@ module Beaneater
160
198
  # Transmits a command which requires the job to be reserved.
161
199
  #
162
200
  # @param [String] cmd Beanstalkd command to send.
163
- # @return [Hash] Beanstalkd response for the command.
201
+ # @return [Hash{Symbol => String,Number}] Beanstalkd response for the command.
164
202
  # @raise [Beaneater::JobNotReserved] Command cannot execute since job is not reserved.
165
203
  # @example
166
204
  # with_reserved("bury 26") { @reserved = false }
@@ -1,6 +1,6 @@
1
- # Simple ruby client for beanstalkd.
1
+ # Simple ruby client for interacting with beanstalkd.
2
2
  module Beaneater
3
- # Represents collection of connections.
3
+ # Represents collection of beanstalkd connections.
4
4
  class Pool
5
5
  # Default number of retries to send a command to a connection
6
6
  MAX_RETRIES = 3
@@ -11,8 +11,7 @@ module Beaneater
11
11
 
12
12
  # Initialize new connection
13
13
  #
14
- # @param [Array] hosts Array of beanstalkd server host
15
- #
14
+ # @param [Array<String>] addresses Array of beanstalkd server addresses
16
15
  # @example
17
16
  # Beaneater::Pool.new(['localhost:11300', '127.0.0.1:11300'])
18
17
  #
@@ -20,54 +19,92 @@ module Beaneater
20
19
  # @bp = Beaneater::Pool.new
21
20
  # @bp.connections.first.host # => 'localhost'
22
21
  # @bp.connections.last.host # => '127.0.0.1'
23
- def initialize(hosts=nil)
24
- hosts = hosts || host_from_env
25
- @connections = Array(hosts).map { |h| Connection.new(h) }
22
+ #
23
+ def initialize(addresses=nil)
24
+ addresses = addresses || host_from_env
25
+ @connections = Array(addresses).map { |a| Connection.new(a) }
26
26
  end
27
27
 
28
- # Returns Beaneater::Stats object
28
+ # Returns Beaneater::Stats object for accessing beanstalk stats.
29
29
  #
30
+ # @return [Beaneater::Stats] stats object
30
31
  # @api public
31
32
  def stats
32
33
  @stats ||= Stats.new(self)
33
34
  end
34
35
 
35
- # Returns Beaneater::Jobs object
36
+ # Returns Beaneater::Jobs object for accessing job related functions.
36
37
  #
38
+ # @return [Beaneater::Jobs] jobs object
37
39
  # @api public
38
40
  def jobs
39
41
  @jobs ||= Jobs.new(self)
40
42
  end
41
43
 
42
- # Returns Beaneater::Tubes object
44
+ # Returns Beaneater::Tubes object for accessing tube related functions.
43
45
  #
46
+ # @return [Beaneater::Tubes] tubes object
44
47
  # @api public
45
48
  def tubes
46
49
  @tubes ||= Tubes.new(self)
47
50
  end
48
51
 
49
- # Send command to every beanstalkd servers set in pool
52
+ # Sends command to every beanstalkd server set in the pool.
50
53
  #
51
54
  # @param [String] command Beanstalkd command
52
- # @param [Hash] options telnet connections options
53
- # @param [Proc] block Block passed in telnet connection object
54
- #
55
+ # @param [Hash{String => String, Boolean}] options telnet connections options
56
+ # @param [Proc] block Block passed to telnet connection during transmit
57
+ # @return [Array<Hash{String => String, Number}>] Beanstalkd command response from each instance
55
58
  # @example
56
59
  # @pool.transmit_to_all("stats")
60
+ #
57
61
  def transmit_to_all(command, options={}, &block)
58
- connections.map do |conn|
59
- safe_transmit { conn.transmit(command, options, &block) }
60
- end
62
+ res_exception = nil
63
+ res = connections.map { |conn|
64
+ begin
65
+ safe_transmit { conn.transmit(command, options, &block) }
66
+ rescue UnexpectedResponse => ex # not the correct status
67
+ res_exception = ex
68
+ nil
69
+ end
70
+ }.compact
71
+ raise res_exception if res.none? && res_exception
72
+ res
61
73
  end
62
74
 
63
- # Send command to a random beanstalkd servers set in pool
75
+ # Send command to each beanstalkd servers until getting response expected
64
76
  #
65
77
  # @param [String] command Beanstalkd command
66
- # @param [Hash] options telnet connections options
78
+ # @param [Hash{String => String, Boolean}] options telnet connections options
67
79
  # @param [Proc] block Block passed in telnet connection object
80
+ # @return [Array<Hash{String => String, Number}>] Beanstalkd command response from the instance
81
+ # @example
82
+ # @pool.transmit_until_res('peek-ready', :status => "FOUND", &block)
83
+ #
84
+ def transmit_until_res(command, options={}, &block)
85
+ status_expected = options.delete(:status)
86
+ res_exception = nil
87
+ connections.each do |conn|
88
+ begin
89
+ res = safe_transmit { conn.transmit(command, options, &block) }
90
+ return res if res[:status] == status_expected
91
+ rescue UnexpectedResponse => ex # not the correct status
92
+ res_exception = ex
93
+ next
94
+ end
95
+ end
96
+ raise res_exception if res_exception
97
+ end
98
+
99
+ # Sends command to a random beanstalkd server in the pool.
68
100
  #
101
+ # @param [String] command Beanstalkd command
102
+ # @param [Hash{String => String,Boolean}] options telnet connections options
103
+ # @param [Proc] block Block passed in telnet connection object
104
+ # @return [Array<Hash{String => String, Number}>] Beanstalkd command response from the instance
69
105
  # @example
70
106
  # @pool.transmit_to_rand("stats", :match => /\n/)
107
+ #
71
108
  def transmit_to_rand(command, options={}, &block)
72
109
  safe_transmit do
73
110
  conn = connections.respond_to?(:sample) ? connections.sample : connections.choice
@@ -75,23 +112,11 @@ module Beaneater
75
112
  end
76
113
  end
77
114
 
78
- # Send command to each beanstalkd servers until getting response expected
79
- #
80
- # @param [String] command Beanstalkd command
81
- # @param [Hash] options telnet connections options
82
- # @param [Proc] block Block passed in telnet connection object
115
+ # Closes all connections within the pool.
83
116
  #
84
117
  # @example
85
- # @pool.transmit_until_res('peek-ready', :status => "FOUND", &block)
86
- def transmit_until_res(command, options={}, &block)
87
- status_expected = options.delete(:status)
88
- connections.each do |conn|
89
- res = safe_transmit { conn.transmit(command, options, &block) }
90
- return res if res[:status] == status_expected
91
- end && nil
92
- end
93
-
94
- # Closes all connections within pool
118
+ # @pool.close
119
+ #
95
120
  def close
96
121
  while @connections.any?
97
122
  conn = @connections.pop
@@ -14,20 +14,21 @@ module Beaneater
14
14
  @pool = pool
15
15
  end
16
16
 
17
- # Delegate to Pool#transmit_to_all and if needed will merge responses from beanstalkd
17
+ # Delegate to Pool#transmit_to_all and if needed will merge responses from beanstalkd.
18
18
  #
19
19
  # @param [String] body Beanstalkd command
20
- # @param [Hash] options telnet connections options
20
+ # @param [Hash{String => String, Boolean}] options telnet connections options
21
21
  # @option options [Boolean] merge Ask for merging responses or not
22
22
  # @param [Proc] block Block passed in telnet connection object
23
- #
24
23
  # @example
25
24
  # @pool.transmit_to_all("stats")
25
+ #
26
26
  def transmit_to_all(body, options={}, &block)
27
27
  merge = options.delete(:merge)
28
28
  res = pool.transmit_to_all(body, options, &block)
29
- if merge
30
- res = { :status => res.first[:status], :body => sum_hashes(res.map { |r| r[:body] }) }
29
+ first = res.find { |r| r && r[:status] }
30
+ if first && merge
31
+ res = { :status => first[:status], :body => sum_items(res.map { |r| r[:body] }) }
31
32
  end
32
33
  res
33
34
  end
@@ -44,17 +45,24 @@ module Beaneater
44
45
 
45
46
  protected
46
47
 
47
- # Selects hashes from collection and then merges the individual key values
48
+ # Selects items from collection and then merges the individual values
49
+ # Supports array of hashes or array of arrays
48
50
  #
49
- # @param [Array<Hash>] hs Collection of hash responses returned from beanstalkd
50
- # @return [Hash] Merged responses combining values from all the hash bodies
51
+ # @param [Array<Hash, Array>] hs Collection of responses returned from beanstalkd
52
+ # @return [Hash{Symbol => String}] Merged responses combining values from all the hash bodies
51
53
  # @example
52
- # self.sum_hashes([{ :foo => 1, :bar => 5 }, { :foo => 2, :bar => 3 }])
54
+ # self.sum_items([{ :foo => 1, :bar => 5 }, { :foo => 2, :bar => 3 }])
53
55
  # => { :foo => 3, :bar => 8 }
56
+ # self.sum_items([['foo', 'bar'], ['foo', 'bar', 'baz']])
57
+ # => ['foo', 'bar', 'baz']
54
58
  #
55
- def sum_hashes(hs)
56
- hs.select { |h| h.is_a?(Hash) }.
57
- inject({}) { |a,b| a.merge(b) { |k,o,n| combine_stats(k, o, n) } }
59
+ def sum_items(items)
60
+ if items.first.is_a?(Hash)
61
+ items.select { |h| h.is_a?(Hash) }.
62
+ inject({}) { |a,b| a.merge(b) { |k,o,n| combine_stats(k, o, n) } }
63
+ elsif items.first.is_a?(Array)
64
+ items.flatten.uniq
65
+ end
58
66
  end
59
67
 
60
68
  # Combine two values for given key
@@ -3,7 +3,7 @@ module Beaneater
3
3
  class StatStruct < FasterOpenStruct
4
4
  # Convert a stats hash into a struct.
5
5
  #
6
- # @param [Hash(String => String)] hash Hash Stats hash to convert to struct
6
+ # @param [Hash{String => String}] hash Hash Stats hash to convert to struct
7
7
  # @return [Beaneater::StatStruct, nil] Stats struct from hash
8
8
  # @example
9
9
  # s = StatStruct.from_hash(:foo => "bar")
@@ -18,7 +18,7 @@ module Beaneater
18
18
  # Access value for stat with specified key.
19
19
  #
20
20
  # @param [String] key Key to fetch from stats.
21
- # @return [String,Integer] Value for specified stat key.
21
+ # @return [String, Integer] Value for specified stat key.
22
22
  # @example
23
23
  # @stats['foo'] # => "bar"
24
24
  #
@@ -10,6 +10,7 @@ module Beaneater
10
10
  # @example
11
11
  # @bp.stats.keys # => ["version", "total_connections"]
12
12
  #
13
+ # @api public
13
14
  def keys
14
15
  data.keys
15
16
  end
@@ -22,6 +22,7 @@ module Beaneater
22
22
  # @pool.tubes['tube2']
23
23
  # # => <Beaneater::Tube name="tube2">
24
24
  #
25
+ # @api public
25
26
  def find(tube_name)
26
27
  Tube.new(self.pool, tube_name)
27
28
  end
@@ -37,6 +38,7 @@ module Beaneater
37
38
  # @conn.tubes.reserve { |job| process(job) }
38
39
  # # => <Beaneater::Job id=5 body="foo">
39
40
  #
41
+ # @api public
40
42
  def reserve(timeout=nil, &block)
41
43
  res = transmit_to_rand(timeout ? "reserve-with-timeout #{timeout}" : 'reserve')
42
44
  job = Job.new(res)
@@ -44,20 +46,6 @@ module Beaneater
44
46
  job
45
47
  end
46
48
 
47
- # Set specified tube as used.
48
- #
49
- # @param [String] tube Tube to be used.
50
- # @example
51
- # @conn.tubes.use("some-tube")
52
- #
53
- def use(tube)
54
- return tube if @last_used == tube
55
- res = transmit_to_all("use #{tube}")
56
- @last_used = tube
57
- rescue BadFormatError
58
- raise InvalidTubeName, "Tube cannot be named '#{tube}'"
59
- end
60
-
61
49
  # List of all known beanstalk tubes.
62
50
  #
63
51
  # @return [Array<Beaneater::Tube>] List of all beanstalk tubes.
@@ -65,8 +53,9 @@ module Beaneater
65
53
  # @pool.tubes.all
66
54
  # # => [<Beaneater::Tube name="tube2">, <Beaneater::Tube name="tube3">]
67
55
  #
56
+ # @api public
68
57
  def all
69
- transmit_to_rand('list-tubes')[:body].map { |tube_name| Tube.new(self.pool, tube_name) }
58
+ transmit_to_all('list-tubes', :merge => true)[:body].map { |tube_name| Tube.new(self.pool, tube_name) }
70
59
  end
71
60
 
72
61
  # List of watched beanstalk tubes.
@@ -76,8 +65,9 @@ module Beaneater
76
65
  # @pool.tubes.watched
77
66
  # # => [<Beaneater::Tube name="tube2">, <Beaneater::Tube name="tube3">]
78
67
  #
68
+ # @api public
79
69
  def watched
80
- transmit_to_rand('list-tubes-watched')[:body].map { |tube_name| Tube.new(self.pool, tube_name) }
70
+ transmit_to_all('list-tubes-watched', :merge => true)[:body].map { |tube_name| Tube.new(self.pool, tube_name) }
81
71
  end
82
72
 
83
73
  # Currently used beanstalk tube.
@@ -87,6 +77,7 @@ module Beaneater
87
77
  # @pool.tubes.used
88
78
  # # => <Beaneater::Tube name="tube2">
89
79
  #
80
+ # @api public
90
81
  def used
91
82
  Tube.new(self.pool, transmit_to_rand('list-tube-used')[:id])
92
83
  end
@@ -98,6 +89,7 @@ module Beaneater
98
89
  # @example
99
90
  # @pool.tubes.watch('foo', 'bar')
100
91
  #
92
+ # @api public
101
93
  def watch(*names)
102
94
  names.each do |t|
103
95
  transmit_to_all "watch #{t}"
@@ -113,6 +105,7 @@ module Beaneater
113
105
  # @example
114
106
  # @pool.tubes.watch!('foo', 'bar')
115
107
  #
108
+ # @api public
116
109
  def watch!(*names)
117
110
  old_tubes = watched.map(&:name) - names.map(&:to_s)
118
111
  watch(*names)
@@ -125,10 +118,25 @@ module Beaneater
125
118
  # @example
126
119
  # @pool.tubes.ignore('foo', 'bar')
127
120
  #
121
+ # @api public
128
122
  def ignore(*names)
129
123
  names.each do |w|
130
124
  transmit_to_all "ignore #{w}"
131
125
  end
132
126
  end
127
+
128
+ # Set specified tube as used.
129
+ #
130
+ # @param [String] tube Tube to be used.
131
+ # @example
132
+ # @conn.tubes.use("some-tube")
133
+ #
134
+ def use(tube)
135
+ return tube if @last_used == tube
136
+ res = transmit_to_all("use #{tube}")
137
+ @last_used = tube
138
+ rescue BadFormatError
139
+ raise InvalidTubeName, "Tube cannot be named '#{tube}'"
140
+ end
133
141
  end # Tubes
134
142
  end # Beaneater
@@ -28,11 +28,11 @@ module Beaneater
28
28
  # Inserts job with specified body onto tube.
29
29
  #
30
30
  # @param [String] body The data to store with this job.
31
- # @param [Hash] options The settings associated with this job.
31
+ # @param [Hash{String => Integer}] options The settings associated with this job.
32
32
  # @option options [Integer] pri priority for this job
33
33
  # @option options [Integer] ttr time to respond for this job
34
34
  # @option options [Integer] delay delay for this job
35
- # @return [Hash] beanstalkd command response
35
+ # @return [Hash{String => String, Number}] beanstalkd command response
36
36
  # @example
37
37
  # @tube.put "data", :pri => 1000, :ttr => 10, :delay => 5
38
38
  #
@@ -71,6 +71,7 @@ module Beaneater
71
71
  # @example
72
72
  # @tube.reserve # => <Beaneater::Job id=5 body=foo>
73
73
  #
74
+ # @api public
74
75
  def reserve(timeout=nil, &block)
75
76
  pool.tubes.watch!(self.name)
76
77
  pool.tubes.reserve(timeout, &block)
@@ -79,10 +80,11 @@ module Beaneater
79
80
  # Kick specified number of jobs from buried to ready state.
80
81
  #
81
82
  # @param [Integer] bounds The number of jobs to kick.
82
- # @return [Hash] Beanstalkd command response
83
+ # @return [Hash{String => String, Number}] Beanstalkd command response
83
84
  # @example
84
85
  # @tube.kick(5)
85
86
  #
87
+ # @api public
86
88
  def kick(bounds=1)
87
89
  safe_use { transmit_to_rand("kick #{bounds}") }
88
90
  end
@@ -93,6 +95,7 @@ module Beaneater
93
95
  # @example
94
96
  # @tube.stats.delayed # => 24
95
97
  #
98
+ # @api public
96
99
  def stats
97
100
  res = transmit_to_all("stats-tube #{name}", :merge => true)
98
101
  StatStruct.from_hash(res[:body])
@@ -101,10 +104,11 @@ module Beaneater
101
104
  # Pause the execution of this tube for specified `delay`.
102
105
  #
103
106
  # @param [Integer] delay Number of seconds to delay tube execution
104
- # @return [Hash] Beanstalkd command response
107
+ # @return [Array<Hash{String => String, Number}>] Beanstalkd command response
105
108
  # @example
106
109
  # @tube.pause(10)
107
110
  #
111
+ # @api public
108
112
  def pause(delay)
109
113
  transmit_to_all("pause-tube #{name} #{delay}")
110
114
  end
@@ -1,4 +1,4 @@
1
1
  module Beaneater
2
2
  # Current version of gem.
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
data/lib/beaneater.rb CHANGED
@@ -4,7 +4,6 @@ require 'net/telnet'
4
4
  require "beaneater/#{f}"
5
5
  end
6
6
 
7
- # Simple ruby client for beanstalkd.
8
7
  module Beaneater
9
-
8
+ # Simple ruby client for beanstalkd.
10
9
  end
@@ -3,6 +3,7 @@ require File.expand_path('../test_helper', __FILE__)
3
3
  describe "beanstalk-client" do
4
4
  before do
5
5
  @beanstalk = Beaneater::Pool.new(['127.0.0.1:11300'])
6
+ # @beanstalk = Beaneater::Pool.new(['127.0.0.1:11300', '127.0.0.1:11301'])
6
7
  @tubes = ['one', 'two', 'three']
7
8
 
8
9
  # Put something on each tube so they exist
data/test/job_test.rb CHANGED
@@ -207,6 +207,44 @@ describe Beaneater::Job do
207
207
  end
208
208
  end # tube
209
209
 
210
+ describe "for #pri" do
211
+ before do
212
+ @tube.put 'bar', :pri => 1
213
+ @job = @tube.peek(:ready)
214
+ end
215
+
216
+ it("should return pri") do
217
+ job = @tube.reserve
218
+ assert_equal 1, job.pri
219
+ job.release
220
+ end
221
+ end # tube
222
+
223
+
224
+ describe "for #ttr" do
225
+ before do
226
+ @tube.put 'bar', :ttr => 5
227
+ @job = @tube.peek(:ready)
228
+ end
229
+
230
+ it("should return ttr") do
231
+ job = @tube.reserve
232
+ assert_equal 5, job.ttr
233
+ job.release
234
+ end
235
+ end # tube
236
+
237
+ describe "for #delay" do
238
+ before do
239
+ @tube.put 'bar', :delay => 5
240
+ @job = @tube.peek(:delayed)
241
+ end
242
+
243
+ it("should return delay") do
244
+ assert_equal 5, @job.delay
245
+ end
246
+ end # tube
247
+
210
248
  after do
211
249
  cleanup_tubes!(['tube'])
212
250
  end
data/test/jobs_test.rb CHANGED
@@ -33,6 +33,30 @@ describe Beaneater::Jobs do
33
33
  end
34
34
  end # find
35
35
 
36
+ describe "for #find_all" do
37
+ before do
38
+ @time = Time.now.to_i
39
+ @tube.put("foo find #{@time}")
40
+ @job = @tube.peek(:ready)
41
+ end
42
+
43
+ it "should return job from id" do
44
+ assert_equal "foo find #{@time}", @jobs.find_all(@job.id).first.body
45
+ end
46
+
47
+ it "should return job using peek" do
48
+ assert_equal "foo find #{@time}", @jobs.find_all(@job.id).first.body
49
+ end
50
+
51
+ it "should return job using hash syntax" do
52
+ assert_equal "foo find #{@time}", @jobs.find_all(@job.id).first.body
53
+ end
54
+
55
+ it "should return nil for invalid id" do
56
+ assert_equal [], @jobs.find_all(-1)
57
+ end
58
+ end # find_all
59
+
36
60
  describe "for #register!" do
37
61
  before do
38
62
  $foo = 0
@@ -18,27 +18,49 @@ describe Beaneater::PoolCommand do
18
18
  describe 'for #transmit_to_all' do
19
19
  describe 'for regular command' do
20
20
  before do
21
- @pool = stub(:transmit_to_all => "OK")
21
+ @pool = stub(:transmit_to_all => [{ :body => "foo", :status => "OK" }])
22
22
  @command = Beaneater::PoolCommand.new(@pool)
23
23
  end
24
24
 
25
25
  it "can run regular command" do
26
- assert_equal "OK", @command.transmit_to_all("foo")
26
+ res = @command.transmit_to_all("foo")
27
+ assert_equal "OK", res[0][:status]
28
+ assert_equal "foo", res[0][:body]
27
29
  end
28
30
  end # regular command
29
31
 
30
- describe 'for merged command' do
32
+ describe 'for merge command with hashes' do
31
33
  before do
32
- @pool = stub(:transmit_to_all => [{ :body => { 'x' => 1, 'version' => 1.1 }}, {:body => { 'x' => 3,'version' => 1.2 }}])
34
+ @pool = stub(:transmit_to_all => [
35
+ { :body => { 'x' => 1, 'version' => 1.1 }, :status => "OK"},
36
+ { :body => { 'x' => 3,'version' => 1.2 }, :status => "OK" }
37
+ ])
33
38
  @command = Beaneater::PoolCommand.new(@pool)
34
39
  end
35
40
 
36
- it "can run merge command" do
41
+ it "can run merge command " do
37
42
  cmd = @command.transmit_to_all("bar", :merge => true)
43
+ assert_equal "OK", cmd[:status]
38
44
  assert_equal 4, cmd[:body]['x']
39
45
  assert_equal Set[1.1, 1.2], cmd[:body]['version']
40
46
  end
41
47
  end # merged command
48
+
49
+ describe 'for merge command with arrays' do
50
+ before do
51
+ @pool = stub(:transmit_to_all => [
52
+ { :body => ['foo', 'bar'], :status => "OK"},
53
+ { :body => ['foo', 'bar', 'baz'], :status => "OK" }
54
+ ])
55
+ @command = Beaneater::PoolCommand.new(@pool)
56
+ end
57
+
58
+ it "can run merge command " do
59
+ cmd = @command.transmit_to_all("bar", :merge => true)
60
+ assert_equal "OK", cmd[:status]
61
+ assert_equal ['foo', 'bar', 'baz'].sort, cmd[:body].sort
62
+ end
63
+ end # merged command
42
64
  end # transmit_to_all
43
65
 
44
66
  describe 'for #method_missing' do
data/test/stats_test.rb CHANGED
@@ -4,7 +4,8 @@ require File.expand_path('../test_helper', __FILE__)
4
4
 
5
5
  describe Beaneater::Stats do
6
6
  before do
7
- @pool = stub(:transmit_to_all => [{ :body => { 'uptime' => 1, 'cmd-use' => 2 }}, {:body => { 'uptime' => 3,'cmd-use' => 4 }}])
7
+ @pool = stub(:transmit_to_all => [{ :body => { 'uptime' => 1, 'cmd-use' => 2 }, :status => "OK"},
8
+ {:body => { 'uptime' => 3,'cmd-use' => 4 }, :status => "OK" }])
8
9
  @stats = Beaneater::Stats.new(@pool)
9
10
  end
10
11
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beaneater
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-02 00:00:00.000000000 Z
12
+ date: 2012-11-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -100,10 +100,10 @@ extra_rdoc_files: []
100
100
  files:
101
101
  - .gitignore
102
102
  - .yardopts
103
+ - CHANGELOG.md
103
104
  - Gemfile
104
105
  - LICENSE.txt
105
106
  - README.md
106
- - REF
107
107
  - Rakefile
108
108
  - TODO
109
109
  - beaneater.gemspec
@@ -147,18 +147,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
147
147
  - - ! '>='
148
148
  - !ruby/object:Gem::Version
149
149
  version: '0'
150
- segments:
151
- - 0
152
- hash: -2674763772608009517
153
150
  required_rubygems_version: !ruby/object:Gem::Requirement
154
151
  none: false
155
152
  requirements:
156
153
  - - ! '>='
157
154
  - !ruby/object:Gem::Version
158
155
  version: '0'
159
- segments:
160
- - 0
161
- hash: -2674763772608009517
162
156
  requirements: []
163
157
  rubyforge_project:
164
158
  rubygems_version: 1.8.24
data/REF DELETED
@@ -1,23 +0,0 @@
1
- # Summary of what this does
2
- #
3
- # @!attribute [r] count
4
- # @param [type] Name description
5
- # @option name [Types] option_key (default_value) description
6
- # @yield [a, b, c] Gives 3 random numbers to the block
7
- # @return [type] description
8
- # @raise [Types] description
9
- # @example
10
- # something.foo # => "test"
11
- #
12
-
13
-
14
- # Summary of what this does
15
- #
16
- # @param [type] Name description
17
- # @option name [Types] option_key (default_value) description
18
- # @yield [a, b, c] Gives 3 random numbers to the block
19
- # @return [type] description
20
- # @raise [Types] description
21
- # @example
22
- # something.foo # => "test"
23
- #