beetle 0.2.6 → 0.2.9
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.
- 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
|