beaneater 0.3.0 → 1.1.0
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.
- checksums.yaml +7 -0
- data/.travis.yml +14 -0
- data/CHANGELOG.md +31 -1
- data/Gemfile +5 -1
- data/README.md +50 -26
- data/Rakefile +3 -1
- data/beaneater.gemspec +1 -1
- data/examples/demo.rb +1 -2
- data/lib/beaneater.rb +57 -4
- data/lib/beaneater/configuration.rb +3 -1
- data/lib/beaneater/connection.rb +135 -30
- data/lib/beaneater/errors.rb +4 -4
- data/lib/beaneater/job/collection.rb +67 -37
- data/lib/beaneater/job/record.rb +42 -30
- data/lib/beaneater/stats.rb +28 -5
- data/lib/beaneater/stats/fast_struct.rb +1 -1
- data/lib/beaneater/stats/stat_struct.rb +8 -2
- data/lib/beaneater/tube/collection.rb +67 -26
- data/lib/beaneater/tube/record.rb +45 -27
- data/lib/beaneater/version.rb +2 -2
- data/test/beaneater_test.rb +5 -11
- data/test/connection_test.rb +55 -1
- data/test/errors_test.rb +9 -2
- data/test/job_test.rb +8 -12
- data/test/jobs_test.rb +15 -43
- data/test/prompt_regexp_test.rb +14 -2
- data/test/stat_struct_test.rb +12 -2
- data/test/stats_test.rb +9 -9
- data/test/test_helper.rb +34 -10
- data/test/tube_test.rb +12 -23
- data/test/tubes_test.rb +61 -56
- metadata +25 -65
- data/lib/beaneater/pool.rb +0 -166
- data/lib/beaneater/pool_command.rb +0 -79
- data/test/pool_command_test.rb +0 -90
- data/test/pool_test.rb +0 -180
metadata
CHANGED
@@ -1,110 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beaneater
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Nico Taing
|
9
|
-
autorequire:
|
8
|
+
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2021-04-26 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: minitest
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 4.1.0
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 4.1.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: mocha
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - ">="
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: fakeweb
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
|
-
requirements:
|
67
|
-
- - ! '>='
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '0'
|
70
|
-
type: :development
|
71
|
-
prerelease: false
|
72
|
-
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
|
-
requirements:
|
75
|
-
- - ! '>='
|
52
|
+
- - ">="
|
76
53
|
- !ruby/object:Gem::Version
|
77
54
|
version: '0'
|
78
55
|
- !ruby/object:Gem::Dependency
|
79
56
|
name: term-ansicolor
|
80
57
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
58
|
requirements:
|
83
|
-
- -
|
59
|
+
- - ">="
|
84
60
|
- !ruby/object:Gem::Version
|
85
61
|
version: '0'
|
86
62
|
type: :development
|
87
63
|
prerelease: false
|
88
64
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
65
|
requirements:
|
91
|
-
- -
|
66
|
+
- - ">="
|
92
67
|
- !ruby/object:Gem::Version
|
93
68
|
version: '0'
|
94
69
|
- !ruby/object:Gem::Dependency
|
95
70
|
name: json
|
96
71
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
72
|
requirements:
|
99
|
-
- -
|
73
|
+
- - ">="
|
100
74
|
- !ruby/object:Gem::Version
|
101
75
|
version: '0'
|
102
76
|
type: :development
|
103
77
|
prerelease: false
|
104
78
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
79
|
requirements:
|
107
|
-
- -
|
80
|
+
- - ">="
|
108
81
|
- !ruby/object:Gem::Version
|
109
82
|
version: '0'
|
110
83
|
description: Simple beanstalkd client for ruby
|
@@ -114,8 +87,9 @@ executables: []
|
|
114
87
|
extensions: []
|
115
88
|
extra_rdoc_files: []
|
116
89
|
files:
|
117
|
-
- .gitignore
|
118
|
-
- .
|
90
|
+
- ".gitignore"
|
91
|
+
- ".travis.yml"
|
92
|
+
- ".yardopts"
|
119
93
|
- CHANGELOG.md
|
120
94
|
- Gemfile
|
121
95
|
- LICENSE.txt
|
@@ -131,8 +105,6 @@ files:
|
|
131
105
|
- lib/beaneater/job.rb
|
132
106
|
- lib/beaneater/job/collection.rb
|
133
107
|
- lib/beaneater/job/record.rb
|
134
|
-
- lib/beaneater/pool.rb
|
135
|
-
- lib/beaneater/pool_command.rb
|
136
108
|
- lib/beaneater/stats.rb
|
137
109
|
- lib/beaneater/stats/fast_struct.rb
|
138
110
|
- lib/beaneater/stats/stat_struct.rb
|
@@ -145,8 +117,6 @@ files:
|
|
145
117
|
- test/errors_test.rb
|
146
118
|
- test/job_test.rb
|
147
119
|
- test/jobs_test.rb
|
148
|
-
- test/pool_command_test.rb
|
149
|
-
- test/pool_test.rb
|
150
120
|
- test/prompt_regexp_test.rb
|
151
121
|
- test/stat_struct_test.rb
|
152
122
|
- test/stats_test.rb
|
@@ -154,34 +124,27 @@ files:
|
|
154
124
|
- test/tube_test.rb
|
155
125
|
- test/tubes_test.rb
|
156
126
|
homepage: ''
|
157
|
-
licenses:
|
158
|
-
|
127
|
+
licenses:
|
128
|
+
- MIT
|
129
|
+
metadata: {}
|
130
|
+
post_install_message:
|
159
131
|
rdoc_options: []
|
160
132
|
require_paths:
|
161
133
|
- lib
|
162
134
|
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
-
none: false
|
164
135
|
requirements:
|
165
|
-
- -
|
136
|
+
- - ">="
|
166
137
|
- !ruby/object:Gem::Version
|
167
138
|
version: '0'
|
168
|
-
segments:
|
169
|
-
- 0
|
170
|
-
hash: -394754542791428871
|
171
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
|
-
none: false
|
173
140
|
requirements:
|
174
|
-
- -
|
141
|
+
- - ">="
|
175
142
|
- !ruby/object:Gem::Version
|
176
143
|
version: '0'
|
177
|
-
segments:
|
178
|
-
- 0
|
179
|
-
hash: -394754542791428871
|
180
144
|
requirements: []
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
specification_version: 3
|
145
|
+
rubygems_version: 3.0.8
|
146
|
+
signing_key:
|
147
|
+
specification_version: 4
|
185
148
|
summary: Simple beanstalkd client for ruby.
|
186
149
|
test_files:
|
187
150
|
- test/beaneater_test.rb
|
@@ -189,12 +152,9 @@ test_files:
|
|
189
152
|
- test/errors_test.rb
|
190
153
|
- test/job_test.rb
|
191
154
|
- test/jobs_test.rb
|
192
|
-
- test/pool_command_test.rb
|
193
|
-
- test/pool_test.rb
|
194
155
|
- test/prompt_regexp_test.rb
|
195
156
|
- test/stat_struct_test.rb
|
196
157
|
- test/stats_test.rb
|
197
158
|
- test/test_helper.rb
|
198
159
|
- test/tube_test.rb
|
199
160
|
- test/tubes_test.rb
|
200
|
-
has_rdoc:
|
data/lib/beaneater/pool.rb
DELETED
@@ -1,166 +0,0 @@
|
|
1
|
-
# Simple ruby client for interacting with beanstalkd.
|
2
|
-
module Beaneater
|
3
|
-
# Represents collection of beanstalkd connections.
|
4
|
-
class Pool
|
5
|
-
# Default number of retries to send a command to a connection
|
6
|
-
MAX_RETRIES = 3
|
7
|
-
|
8
|
-
# @!attribute connections
|
9
|
-
# @return [Array<Beaneater::Connection>] returns Collection of connections
|
10
|
-
attr_reader :connections
|
11
|
-
|
12
|
-
# Initialize new connection
|
13
|
-
#
|
14
|
-
# @param [Array<String>] addresses Array of beanstalkd server addresses
|
15
|
-
# @example
|
16
|
-
# Beaneater::Pool.new(['localhost:11300', '127.0.0.1:11300'])
|
17
|
-
#
|
18
|
-
# ENV['BEANSTALKD_URL'] = 'localhost:11300,127.0.0.1:11300'
|
19
|
-
# @bp = Beaneater::Pool.new
|
20
|
-
# @bp.connections.first.host # => 'localhost'
|
21
|
-
# @bp.connections.last.host # => '127.0.0.1'
|
22
|
-
#
|
23
|
-
def initialize(addresses=nil)
|
24
|
-
addresses = addresses || host_from_env || Beaneater.configuration.beanstalkd_url
|
25
|
-
@connections = Array(addresses).map { |a| Connection.new(a) }
|
26
|
-
end
|
27
|
-
|
28
|
-
# Returns Beaneater::Stats object for accessing beanstalk stats.
|
29
|
-
#
|
30
|
-
# @return [Beaneater::Stats] stats object
|
31
|
-
# @api public
|
32
|
-
def stats
|
33
|
-
@stats ||= Stats.new(self)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Returns Beaneater::Jobs object for accessing job related functions.
|
37
|
-
#
|
38
|
-
# @return [Beaneater::Jobs] jobs object
|
39
|
-
# @api public
|
40
|
-
def jobs
|
41
|
-
@jobs ||= Jobs.new(self)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Returns Beaneater::Tubes object for accessing tube related functions.
|
45
|
-
#
|
46
|
-
# @return [Beaneater::Tubes] tubes object
|
47
|
-
# @api public
|
48
|
-
def tubes
|
49
|
-
@tubes ||= Tubes.new(self)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Sends command to every beanstalkd server set in the pool.
|
53
|
-
#
|
54
|
-
# @param [String] command Beanstalkd command
|
55
|
-
# @param [Hash{String => String, Boolean}] options socket connections options
|
56
|
-
# @param [Proc] block Block passed to socket connection during transmit
|
57
|
-
# @return [Array<Hash{String => String, Number}>] Beanstalkd command response from each instance
|
58
|
-
# @example
|
59
|
-
# @pool.transmit_to_all("stats")
|
60
|
-
#
|
61
|
-
def transmit_to_all(command, options={}, &block)
|
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
|
73
|
-
end
|
74
|
-
|
75
|
-
# Send command to each beanstalkd servers until getting response expected
|
76
|
-
#
|
77
|
-
# @param [String] command Beanstalkd command
|
78
|
-
# @param [Hash{String => String, Boolean}] options socket connections options
|
79
|
-
# @param [Proc] block Block passed in socket 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.
|
100
|
-
#
|
101
|
-
# @param [String] command Beanstalkd command
|
102
|
-
# @param [Hash{String => String,Boolean}] options socket connections options
|
103
|
-
# @param [Proc] block Block passed in socket connection object
|
104
|
-
# @return [Array<Hash{String => String, Number}>] Beanstalkd command response from the instance
|
105
|
-
# @example
|
106
|
-
# @pool.transmit_to_rand("stats", :match => /\n/)
|
107
|
-
#
|
108
|
-
def transmit_to_rand(command, options={}, &block)
|
109
|
-
safe_transmit do
|
110
|
-
conn = connections.respond_to?(:sample) ? connections.sample : connections.choice
|
111
|
-
conn.transmit(command, options, &block)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# Closes all connections within the pool.
|
116
|
-
#
|
117
|
-
# @example
|
118
|
-
# @pool.close
|
119
|
-
#
|
120
|
-
def close
|
121
|
-
while @connections.any?
|
122
|
-
conn = @connections.pop
|
123
|
-
conn.close
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
protected
|
128
|
-
|
129
|
-
# Transmit command to beanstalk connections safely handling failed connections
|
130
|
-
#
|
131
|
-
# @param [Proc] block The command to execute.
|
132
|
-
# @return [Object] Result of the block passed
|
133
|
-
# @raise [Beaneater::DrainingError,Beaneater::NotConnected] Could not connect to Beanstalk client
|
134
|
-
# @example
|
135
|
-
# safe_transmit { conn.transmit('foo') }
|
136
|
-
# # => "result of foo command from beanstalk"
|
137
|
-
#
|
138
|
-
def safe_transmit(&block)
|
139
|
-
retries = 1
|
140
|
-
begin
|
141
|
-
yield
|
142
|
-
rescue DrainingError, EOFError, Errno::ECONNRESET, Errno::EPIPE => ex
|
143
|
-
# TODO remove faulty connections from pool?
|
144
|
-
# https://github.com/kr/beanstalk-client-ruby/blob/master/lib/beanstalk-client/connection.rb#L405-410
|
145
|
-
if retries < MAX_RETRIES
|
146
|
-
retries += 1
|
147
|
-
retry
|
148
|
-
else # finished retrying, fail out
|
149
|
-
ex.is_a?(DrainingError) ? raise(ex) : raise(NotConnected, "Could not connect!")
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end # transmit_call
|
153
|
-
|
154
|
-
# The hosts provided by BEANSTALKD_URL environment variable, if available.
|
155
|
-
#
|
156
|
-
# @return [Array] Set of beanstalkd host addresses
|
157
|
-
# @example
|
158
|
-
# ENV['BEANSTALKD_URL'] = "localhost:1212,localhost:2424"
|
159
|
-
# # => ['localhost:1212', 'localhost:2424']
|
160
|
-
#
|
161
|
-
def host_from_env
|
162
|
-
ENV['BEANSTALKD_URL'].respond_to?(:length) && ENV['BEANSTALKD_URL'].length > 0 && ENV['BEANSTALKD_URL'].split(',').map(&:strip)
|
163
|
-
end
|
164
|
-
|
165
|
-
end # Pool
|
166
|
-
end # Beaneater
|
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
|
3
|
-
module Beaneater
|
4
|
-
# Represents collection of pool related commands.
|
5
|
-
class PoolCommand
|
6
|
-
# @!attribute pool
|
7
|
-
# @return [Beaneater::Pool] returns Pool object
|
8
|
-
attr_reader :pool
|
9
|
-
|
10
|
-
# Initialize new connection
|
11
|
-
#
|
12
|
-
# @param [Beaneater::Pool] pool Pool object
|
13
|
-
def initialize(pool)
|
14
|
-
@pool = pool
|
15
|
-
end
|
16
|
-
|
17
|
-
# Delegate to Pool#transmit_to_all and if needed will merge responses from beanstalkd.
|
18
|
-
#
|
19
|
-
# @param [String] body Beanstalkd command
|
20
|
-
# @param [Hash{String => String, Boolean}] options socket connections options
|
21
|
-
# @option options [Boolean] merge Ask for merging responses or not
|
22
|
-
# @param [Proc] block Block passed in socket connection object
|
23
|
-
# @example
|
24
|
-
# @pool.transmit_to_all("stats")
|
25
|
-
#
|
26
|
-
def transmit_to_all(body, options={}, &block)
|
27
|
-
merge = options.delete(:merge)
|
28
|
-
res = pool.transmit_to_all(body, options, &block)
|
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] }) }
|
32
|
-
end
|
33
|
-
res
|
34
|
-
end
|
35
|
-
|
36
|
-
# Delegate missing methods to pool
|
37
|
-
# @api public
|
38
|
-
def method_missing(name, *args, &block)
|
39
|
-
if pool.respond_to?(name)
|
40
|
-
pool.send(name, *args, &block)
|
41
|
-
else # not a known pool command
|
42
|
-
super
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
protected
|
47
|
-
|
48
|
-
# Selects items from collection and then merges the individual values
|
49
|
-
# Supports array of hashes or array of arrays
|
50
|
-
#
|
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
|
53
|
-
# @example
|
54
|
-
# self.sum_items([{ :foo => 1, :bar => 5 }, { :foo => 2, :bar => 3 }])
|
55
|
-
# => { :foo => 3, :bar => 8 }
|
56
|
-
# self.sum_items([['foo', 'bar'], ['foo', 'bar', 'baz']])
|
57
|
-
# => ['foo', 'bar', 'baz']
|
58
|
-
#
|
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
|
66
|
-
end
|
67
|
-
|
68
|
-
# Combine two values for given key
|
69
|
-
#
|
70
|
-
# @param [String] k key name within response hash
|
71
|
-
# @return [Set,Integer] combined value for stat
|
72
|
-
# @example
|
73
|
-
# self.combine_stats('total_connections', 4, 5) # => 9
|
74
|
-
#
|
75
|
-
def combine_stats(k, a, b)
|
76
|
-
['name', 'version', 'pid'].include?(k) ? Set[a] + Set[b] : a + b
|
77
|
-
end
|
78
|
-
end # PoolCommand
|
79
|
-
end # Beaneater
|