beetle 0.2.6 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- data/RELEASE_NOTES.rdoc +6 -0
- data/beetle.gemspec +2 -2
- data/examples/attempts.rb +13 -13
- data/lib/beetle.rb +5 -0
- data/lib/beetle/client.rb +4 -0
- data/lib/beetle/configuration.rb +12 -7
- data/lib/beetle/message.rb +1 -0
- data/lib/beetle/publisher.rb +3 -0
- data/lib/beetle/subscriber.rb +8 -2
- data/lib/ext/qrack/client.rb +27 -0
- data/test/beetle/client_test.rb +4 -0
- data/test/beetle/configuration_test.rb +2 -2
- data/test/beetle/deduplication_store_test.rb +4 -0
- data/test/beetle/ext_test.rb +26 -0
- data/test/beetle/message_test.rb +1 -1
- data/test/beetle/publisher_test.rb +14 -9
- data/test/beetle/redis_configuration_client_test.rb +4 -0
- data/test/beetle/subscriber_test.rb +16 -3
- metadata +8 -5
data/RELEASE_NOTES.rdoc
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= Release Notes
|
2
2
|
|
3
|
+
== Version 0.2.9
|
4
|
+
|
5
|
+
* Beetle::Client now raises an exception when it fails to publish a message to at least 1 RabbitMQ server
|
6
|
+
* Subscribers are now stopped cleanly to avoid 'closed abruptly' messages in the RabbitMQ server log
|
7
|
+
* Added send and receive timeouts on the socket and use system_timer for ruby side timeouts
|
8
|
+
|
3
9
|
== Version 0.2.6
|
4
10
|
|
5
11
|
* Set dependency on ActiveSupport to 2.3.x since it ain't compatible to version 3.x yet
|
data/beetle.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "beetle"
|
3
|
-
s.version = "0.2.
|
3
|
+
s.version = "0.2.9"
|
4
4
|
|
5
5
|
s.required_rubygems_version = ">= 1.3.1"
|
6
6
|
s.authors = ["Stefan Kaes", "Pascal Friederich", "Ali Jelveh", "Sebastian Roebke"]
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.specification_version = 3
|
32
32
|
s.add_runtime_dependency("uuid4r", [">= 0.1.1"])
|
33
33
|
s.add_runtime_dependency("bunny", [">= 0.6.0"])
|
34
|
-
s.add_runtime_dependency("redis", ["
|
34
|
+
s.add_runtime_dependency("redis", ["= 2.0.4"])
|
35
35
|
s.add_runtime_dependency("amqp", [">= 0.6.7"])
|
36
36
|
s.add_runtime_dependency("activesupport", ["~> 2.3.4"])
|
37
37
|
s.add_runtime_dependency("daemons", [">= 1.0.10"])
|
data/examples/attempts.rb
CHANGED
@@ -14,15 +14,15 @@ require File.expand_path("../lib/beetle", File.dirname(__FILE__))
|
|
14
14
|
Beetle.config.logger.level = Logger::INFO
|
15
15
|
|
16
16
|
# setup client
|
17
|
-
client = Beetle::Client.new
|
18
|
-
client.register_queue(:test)
|
19
|
-
client.register_message(:test)
|
17
|
+
$client = Beetle::Client.new
|
18
|
+
$client.register_queue(:test)
|
19
|
+
$client.register_message(:test)
|
20
20
|
|
21
21
|
# purge the test queue
|
22
|
-
client.purge(:test)
|
22
|
+
$client.purge(:test)
|
23
23
|
|
24
24
|
# empty the dedup store
|
25
|
-
client.deduplication_store.flushdb
|
25
|
+
$client.deduplication_store.flushdb
|
26
26
|
|
27
27
|
# we're starting with 0 exceptions and expect our handler to process the message until the exception count has reached 10
|
28
28
|
$exceptions = 0
|
@@ -32,35 +32,35 @@ $max_exceptions = 10
|
|
32
32
|
# in this example we've not only overwritten the process method but also the
|
33
33
|
# error and failure methods of the handler baseclass
|
34
34
|
class Handler < Beetle::Handler
|
35
|
-
|
35
|
+
|
36
36
|
# called when the handler receives the message - fail everytime
|
37
37
|
def process
|
38
38
|
raise "failed #{$exceptions += 1} times"
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
# called when handler process raised an exception
|
42
42
|
def error(exception)
|
43
43
|
logger.info "execution failed: #{exception}"
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
# called when the handler has finally failed
|
47
47
|
# we're stopping the event loop so this script stops after that
|
48
48
|
def failure(result)
|
49
49
|
super
|
50
|
-
|
50
|
+
$client.stop_listening
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
54
|
# register our handler to the message, configure it to our max_exceptions limit, we configure a delay of 0 to have it not wait before retrying
|
55
|
-
client.register_handler(:test, Handler, :exceptions => $max_exceptions, :delay => 0)
|
55
|
+
$client.register_handler(:test, Handler, :exceptions => $max_exceptions, :delay => 0)
|
56
56
|
|
57
57
|
# publish a our test message
|
58
|
-
client.publish(:test, "snafu")
|
58
|
+
$client.publish(:test, "snafu")
|
59
59
|
|
60
60
|
# and start our listening loop...
|
61
|
-
client.listen
|
61
|
+
$client.listen
|
62
62
|
|
63
63
|
# error handling, if everything went right this shouldn't happen.
|
64
64
|
if $exceptions != $max_exceptions + 1
|
65
65
|
raise "something is fishy. Failed #{$exceptions} times"
|
66
|
-
end
|
66
|
+
end
|
data/lib/beetle.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
$:.unshift(File.expand_path('..', __FILE__))
|
1
2
|
require 'amqp'
|
2
3
|
require 'mq'
|
3
4
|
require 'bunny'
|
@@ -17,6 +18,8 @@ module Beetle
|
|
17
18
|
class UnknownQueue < Error; end
|
18
19
|
# raised when no redis master server can be found
|
19
20
|
class NoRedisMaster < Error; end
|
21
|
+
# raise when no message could be sent by the publisher
|
22
|
+
class NoMessageSent < Error; end
|
20
23
|
|
21
24
|
# AMQP options for exchange creation
|
22
25
|
EXCHANGE_CREATION_KEYS = [:auto_delete, :durable, :internal, :nowait, :passive]
|
@@ -56,3 +59,5 @@ module Beetle
|
|
56
59
|
|
57
60
|
Timer = RUBY_VERSION < "1.9" ? SystemTimer : Timeout
|
58
61
|
end
|
62
|
+
|
63
|
+
require 'ext/qrack/client'
|
data/lib/beetle/client.rb
CHANGED
@@ -24,6 +24,9 @@ module Beetle
|
|
24
24
|
# the AMQP servers available for publishing
|
25
25
|
attr_reader :servers
|
26
26
|
|
27
|
+
# additional AMQP servers available for subscribing. useful for migration scenarios.
|
28
|
+
attr_reader :additional_subscription_servers
|
29
|
+
|
27
30
|
# an options hash for the configured exchanges
|
28
31
|
attr_reader :exchanges
|
29
32
|
|
@@ -46,6 +49,7 @@ module Beetle
|
|
46
49
|
def initialize(config = Beetle.config)
|
47
50
|
@config = config
|
48
51
|
@servers = config.servers.split(/ *, */)
|
52
|
+
@additional_subscription_servers = config.additional_subscription_servers.split(/ *, */)
|
49
53
|
@exchanges = {}
|
50
54
|
@queues = {}
|
51
55
|
@messages = {}
|
data/lib/beetle/configuration.rb
CHANGED
@@ -38,6 +38,8 @@ module Beetle
|
|
38
38
|
|
39
39
|
# list of amqp servers to use (defaults to <tt>"localhost:5672"</tt>)
|
40
40
|
attr_accessor :servers
|
41
|
+
# list of additional amqp servers to use for subscribers (defaults to <tt>""</tt>)
|
42
|
+
attr_accessor :additional_subscription_servers
|
41
43
|
# the virtual host to use on the AMQP servers (defaults to <tt>"/"</tt>)
|
42
44
|
attr_accessor :vhost
|
43
45
|
# the AMQP user to use when connecting to the AMQP servers (defaults to <tt>"guest"</tt>)
|
@@ -63,6 +65,7 @@ module Beetle
|
|
63
65
|
self.redis_configuration_client_ids = ""
|
64
66
|
|
65
67
|
self.servers = "localhost:5672"
|
68
|
+
self.additional_subscription_servers = ""
|
66
69
|
self.vhost = "/"
|
67
70
|
self.user = "guest"
|
68
71
|
self.password = "guest"
|
@@ -77,13 +80,14 @@ module Beetle
|
|
77
80
|
end
|
78
81
|
|
79
82
|
def logger
|
80
|
-
@logger ||=
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
@logger ||=
|
84
|
+
begin
|
85
|
+
l = Logger.new(log_file)
|
86
|
+
l.formatter = Logger::Formatter.new
|
87
|
+
l.level = Logger::INFO
|
88
|
+
l.datetime_format = "%Y-%m-%d %H:%M:%S"
|
89
|
+
l
|
90
|
+
end
|
87
91
|
end
|
88
92
|
|
89
93
|
private
|
@@ -93,6 +97,7 @@ module Beetle
|
|
93
97
|
send("#{key}=", value)
|
94
98
|
end
|
95
99
|
rescue Exception
|
100
|
+
Beetle::reraise_expectation_errors!
|
96
101
|
logger.error "Error loading beetle config file '#{config_file}': #{$!}"
|
97
102
|
raise
|
98
103
|
end
|
data/lib/beetle/message.rb
CHANGED
data/lib/beetle/publisher.rb
CHANGED
@@ -50,6 +50,7 @@ module Beetle
|
|
50
50
|
tries -= 1
|
51
51
|
retry if tries > 0
|
52
52
|
logger.error "Beetle: message could not be delivered: #{message_name}"
|
53
|
+
raise NoMessageSent.new
|
53
54
|
end
|
54
55
|
published
|
55
56
|
end
|
@@ -79,9 +80,11 @@ module Beetle
|
|
79
80
|
case published.size
|
80
81
|
when 0
|
81
82
|
logger.error "Beetle: message could not be delivered: #{message_name}"
|
83
|
+
raise NoMessageSent.new
|
82
84
|
when 1
|
83
85
|
logger.warn "Beetle: failed to send message redundantly"
|
84
86
|
end
|
87
|
+
|
85
88
|
published.size
|
86
89
|
end
|
87
90
|
|
data/lib/beetle/subscriber.rb
CHANGED
@@ -5,6 +5,7 @@ module Beetle
|
|
5
5
|
# create a new subscriber instance
|
6
6
|
def initialize(client, options = {}) #:nodoc:
|
7
7
|
super
|
8
|
+
@servers.concat @client.additional_subscription_servers
|
8
9
|
@handlers = {}
|
9
10
|
@amqp_connections = {}
|
10
11
|
@mqs = {}
|
@@ -30,9 +31,14 @@ module Beetle
|
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
33
|
-
# stops the eventmachine loop
|
34
|
+
# closes all AMQP connections and stops the eventmachine loop
|
34
35
|
def stop! #:nodoc:
|
35
|
-
|
36
|
+
if @amqp_connections.empty?
|
37
|
+
EM.stop_event_loop
|
38
|
+
else
|
39
|
+
server, connection = @amqp_connections.shift
|
40
|
+
connection.close { stop! }
|
41
|
+
end
|
36
42
|
end
|
37
43
|
|
38
44
|
# register handler for the given queues (see Client#register_handler)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'qrack/client'
|
2
|
+
|
3
|
+
|
4
|
+
module Qrack
|
5
|
+
class Client
|
6
|
+
# overwrite the timeout method so that SystemTimer is used
|
7
|
+
# instead the standard timeout.rb: http://ph7spot.com/musings/system-timer
|
8
|
+
delegate :timeout, :to => Beetle::Timer
|
9
|
+
|
10
|
+
def socket_with_reliable_timeout
|
11
|
+
socket_without_reliable_timeout
|
12
|
+
|
13
|
+
secs = Integer(CONNECT_TIMEOUT)
|
14
|
+
usecs = Integer((CONNECT_TIMEOUT - secs) * 1_000_000)
|
15
|
+
optval = [secs, usecs].pack("l_2")
|
16
|
+
|
17
|
+
begin
|
18
|
+
@socket.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
|
19
|
+
@socket.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
|
20
|
+
rescue Errno::ENOPROTOOPT
|
21
|
+
end
|
22
|
+
@socket
|
23
|
+
end
|
24
|
+
alias_method_chain :socket, :reliable_timeout
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/test/beetle/client_test.rb
CHANGED
@@ -11,6 +11,10 @@ module Beetle
|
|
11
11
|
assert_equal ["localhost:5672"], @client.servers
|
12
12
|
end
|
13
13
|
|
14
|
+
test "should have no additional subscription servers" do
|
15
|
+
assert_equal [], @client.additional_subscription_servers
|
16
|
+
end
|
17
|
+
|
14
18
|
test "should have no exchanges" do
|
15
19
|
assert @client.exchanges.empty?
|
16
20
|
end
|
@@ -12,7 +12,7 @@ module Beetle
|
|
12
12
|
config.config_file = "some/path/to/a/file"
|
13
13
|
assert_equal new_value, config.gc_threshold
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
test "should log to STDOUT if no log_file given" do
|
17
17
|
config = Configuration.new
|
18
18
|
Logger.expects(:new).with(STDOUT).returns(stub_everything)
|
@@ -27,4 +27,4 @@ module Beetle
|
|
27
27
|
config.logger
|
28
28
|
end
|
29
29
|
end
|
30
|
-
end
|
30
|
+
end
|
@@ -95,6 +95,8 @@ module Beetle
|
|
95
95
|
redis1.expects(:get).with("foo:x").raises("disconnected").in_sequence(s)
|
96
96
|
@store.expects(:redis).returns(redis2).in_sequence(s)
|
97
97
|
redis2.expects(:get).with("foo:x").returns("42").in_sequence(s)
|
98
|
+
@store.logger.expects(:info)
|
99
|
+
@store.logger.expects(:error)
|
98
100
|
assert_equal("42", @store.get("foo", "x"))
|
99
101
|
end
|
100
102
|
|
@@ -103,6 +105,8 @@ module Beetle
|
|
103
105
|
@store.stubs(:redis).returns(redis1)
|
104
106
|
redis1.stubs(:get).with("foo:x").raises("disconnected")
|
105
107
|
@store.stubs(:sleep)
|
108
|
+
@store.logger.stubs(:info)
|
109
|
+
@store.logger.stubs(:error)
|
106
110
|
assert_raises(NoRedisMaster) { @store.get("foo", "x") }
|
107
111
|
end
|
108
112
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
|
4
|
+
class QrackClientExtTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
Qrack::Client.any_instance.stubs(:create_channel).returns(nil)
|
7
|
+
@client = Qrack::Client.new
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
test "should use system-timer for reliable timeouts" do
|
12
|
+
Beetle::Timer.expects(:timeout)
|
13
|
+
@client.send :timeout, 1, 1 do
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
test "should set send/receive timeouts on the socket" do
|
18
|
+
socket_mock = mock("socket")
|
19
|
+
@client.instance_variable_set(:@socket, socket_mock)
|
20
|
+
@client.stubs(:socket_without_reliable_timeout)
|
21
|
+
|
22
|
+
socket_mock.expects(:setsockopt).with(Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, anything)
|
23
|
+
socket_mock.expects(:setsockopt).with(Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, anything)
|
24
|
+
@client.send(:socket)
|
25
|
+
end
|
26
|
+
end
|
data/test/beetle/message_test.rb
CHANGED
@@ -525,7 +525,7 @@ module Beetle
|
|
525
525
|
test "processing a message catches internal exceptions risen by process_internal and returns an internal error" do
|
526
526
|
header = header_with_params({})
|
527
527
|
message = Message.new("somequeue", header, 'foo', :store => @store)
|
528
|
-
message.expects(:process_internal).raises(Exception.new)
|
528
|
+
message.expects(:process_internal).raises(Exception.new("this is expected"))
|
529
529
|
handler = Handler.new
|
530
530
|
handler.expects(:process_exception).never
|
531
531
|
handler.expects(:process_failure).never
|
@@ -76,13 +76,16 @@ module Beetle
|
|
76
76
|
end
|
77
77
|
|
78
78
|
test "publishing should fail over to the next server" do
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
@pub.
|
83
|
-
|
84
|
-
|
85
|
-
|
79
|
+
@pub.servers << "localhost:3333"
|
80
|
+
raising_exchange = mock("raising exchange")
|
81
|
+
nice_exchange = mock("nice exchange")
|
82
|
+
@pub.stubs(:exchange).with("mama-exchange").returns(raising_exchange).then.returns(nice_exchange)
|
83
|
+
|
84
|
+
raising_exchange.expects(:publish).raises(Bunny::ConnectionError)
|
85
|
+
nice_exchange.expects(:publish)
|
86
|
+
@pub.expects(:set_current_server).twice
|
87
|
+
@pub.expects(:stop!).once
|
88
|
+
@pub.expects(:mark_server_dead).once
|
86
89
|
@pub.publish_with_failover("mama-exchange", "mama", @data, @opts)
|
87
90
|
end
|
88
91
|
|
@@ -114,7 +117,7 @@ module Beetle
|
|
114
117
|
assert_equal 1, @pub.publish_with_redundancy("mama-exchange", "mama", @data, @opts)
|
115
118
|
end
|
116
119
|
|
117
|
-
test "redundant publishing should
|
120
|
+
test "redundant publishing should raise an exception if the message was published to no server" do
|
118
121
|
redundant = sequence("redundant")
|
119
122
|
@pub.servers = ["someserver", "someotherserver"]
|
120
123
|
@pub.server = "someserver"
|
@@ -125,7 +128,9 @@ module Beetle
|
|
125
128
|
@pub.expects(:exchange).with("mama-exchange").returns(e).in_sequence(redundant)
|
126
129
|
e.expects(:publish).raises(Bunny::ConnectionError).in_sequence(redundant)
|
127
130
|
|
128
|
-
|
131
|
+
assert_raises Beetle::NoMessageSent do
|
132
|
+
@pub.publish_with_redundancy("mama-exchange", "mama", @data, @opts)
|
133
|
+
end
|
129
134
|
end
|
130
135
|
|
131
136
|
test "redundant publishing should fallback to failover publishing if less than one server is available" do
|
@@ -65,13 +65,17 @@ module Beetle
|
|
65
65
|
|
66
66
|
test "should clear redis master file if redis from master file is slave" do
|
67
67
|
@client.stubs(:redis_master_from_master_file).returns(stub(:master? => false))
|
68
|
+
Beetle::Client.any_instance.stubs(:publish)
|
68
69
|
@client.expects(:clear_redis_master_file)
|
70
|
+
@client.expects(:client_started!)
|
69
71
|
@client.start
|
70
72
|
end
|
71
73
|
|
72
74
|
test "should clear redis master file if redis from master file is not available" do
|
73
75
|
@client.stubs(:redis_master_from_master_file).returns(nil)
|
76
|
+
Beetle::Client.any_instance.stubs(:publish)
|
74
77
|
@client.expects(:clear_redis_master_file)
|
78
|
+
@client.expects(:client_started!)
|
75
79
|
@client.start
|
76
80
|
end
|
77
81
|
|
@@ -51,6 +51,19 @@ module Beetle
|
|
51
51
|
|
52
52
|
end
|
53
53
|
|
54
|
+
class AdditionalSubscriptionServersTest < Test::Unit::TestCase
|
55
|
+
def setup
|
56
|
+
@config = Configuration.new
|
57
|
+
@config.additional_subscription_servers = "localhost:1234"
|
58
|
+
@client = Client.new(@config)
|
59
|
+
@sub = @client.send(:subscriber)
|
60
|
+
end
|
61
|
+
|
62
|
+
test "subscribers server list should contain addtional subcription hosts" do
|
63
|
+
assert_equal ["localhost:5672", "localhost:1234"], @sub.servers
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
54
67
|
class SubscriberQueueManagementTest < Test::Unit::TestCase
|
55
68
|
def setup
|
56
69
|
@client = Client.new
|
@@ -143,7 +156,7 @@ module Beetle
|
|
143
156
|
|
144
157
|
test "exceptions raised from message processing should be ignored" do
|
145
158
|
header = header_with_params({})
|
146
|
-
Message.any_instance.expects(:process).raises(Exception.new)
|
159
|
+
Message.any_instance.expects(:process).raises(Exception.new("don't worry"))
|
147
160
|
assert_nothing_raised { @callback.call(header, 'foo') }
|
148
161
|
end
|
149
162
|
|
@@ -214,12 +227,12 @@ module Beetle
|
|
214
227
|
proc = lambda do |m|
|
215
228
|
block_called = true
|
216
229
|
assert_equal header, m.header
|
217
|
-
assert_equal "
|
230
|
+
assert_equal "foo", m.data
|
218
231
|
assert_equal server, m.server
|
219
232
|
end
|
220
233
|
@sub.register_handler("some_queue", &proc)
|
221
234
|
q = mock("QUEUE")
|
222
|
-
q.expects(:subscribe).with({:ack => true, :key => "#"}).yields(header,
|
235
|
+
q.expects(:subscribe).with({:ack => true, :key => "#"}).yields(header, "foo")
|
223
236
|
@sub.expects(:queues).returns({"some_queue" => q})
|
224
237
|
@sub.send(:subscribe, "some_queue")
|
225
238
|
assert block_called
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beetle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 9
|
10
|
+
version: 0.2.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Stefan Kaes
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date: 2010-
|
21
|
+
date: 2010-10-27 00:00:00 +02:00
|
22
22
|
default_executable: beetle
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
@@ -59,7 +59,7 @@ dependencies:
|
|
59
59
|
requirement: &id003 !ruby/object:Gem::Requirement
|
60
60
|
none: false
|
61
61
|
requirements:
|
62
|
-
- - "
|
62
|
+
- - "="
|
63
63
|
- !ruby/object:Gem::Version
|
64
64
|
hash: 7
|
65
65
|
segments:
|
@@ -217,6 +217,7 @@ files:
|
|
217
217
|
- lib/beetle/redis_server_info.rb
|
218
218
|
- lib/beetle/subscriber.rb
|
219
219
|
- lib/beetle.rb
|
220
|
+
- lib/ext/qrack/client.rb
|
220
221
|
- features/README.rdoc
|
221
222
|
- features/redis_auto_failover.feature
|
222
223
|
- features/step_definitions/redis_auto_failover_steps.rb
|
@@ -240,6 +241,7 @@ files:
|
|
240
241
|
- test/beetle/client_test.rb
|
241
242
|
- test/beetle/configuration_test.rb
|
242
243
|
- test/beetle/deduplication_store_test.rb
|
244
|
+
- test/beetle/ext_test.rb
|
243
245
|
- test/beetle/handler_test.rb
|
244
246
|
- test/beetle/message_test.rb
|
245
247
|
- test/beetle/publisher_test.rb
|
@@ -293,6 +295,7 @@ test_files:
|
|
293
295
|
- test/beetle/client_test.rb
|
294
296
|
- test/beetle/configuration_test.rb
|
295
297
|
- test/beetle/deduplication_store_test.rb
|
298
|
+
- test/beetle/ext_test.rb
|
296
299
|
- test/beetle/handler_test.rb
|
297
300
|
- test/beetle/message_test.rb
|
298
301
|
- test/beetle/publisher_test.rb
|