bunny 1.4.1 → 1.5.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -1
- data/ChangeLog.md +19 -5
- data/README.md +23 -3
- data/examples/guides/extensions/basic_nack.rb +1 -1
- data/examples/guides/extensions/dead_letter_exchange.rb +1 -1
- data/examples/guides/queues/redeliveries.rb +2 -2
- data/lib/bunny.rb +1 -1
- data/lib/bunny/channel.rb +34 -21
- data/lib/bunny/exceptions.rb +17 -2
- data/lib/bunny/exchange.rb +14 -22
- data/lib/bunny/queue.rb +19 -12
- data/lib/bunny/session.rb +67 -57
- data/lib/bunny/version.rb +1 -1
- data/spec/config/enabled_plugins +1 -0
- data/spec/config/rabbitmq.config +18 -0
- data/spec/higher_level_api/integration/basic_ack_spec.rb +29 -2
- data/spec/higher_level_api/integration/basic_consume_with_objects_spec.rb +1 -1
- data/spec/higher_level_api/integration/basic_nack_spec.rb +5 -5
- data/spec/higher_level_api/integration/basic_reject_spec.rb +3 -3
- data/spec/higher_level_api/integration/connection_recovery_spec.rb +79 -2
- data/spec/higher_level_api/integration/connection_spec.rb +24 -0
- data/spec/higher_level_api/integration/dead_lettering_spec.rb +1 -1
- data/spec/higher_level_api/integration/exchange_unbind_spec.rb +1 -1
- data/spec/higher_level_api/integration/message_properties_access_spec.rb +1 -1
- data/spec/issues/issue78_spec.rb +2 -2
- data/spec/spec_helper.rb +6 -7
- data/spec/tls/ca_certificate.pem +18 -0
- data/spec/tls/ca_key.pem +27 -0
- data/spec/tls/client_cert.pem +16 -16
- data/spec/tls/client_key.pem +25 -25
- data/spec/tls/server_cert.pem +16 -16
- data/spec/tls/server_key.pem +25 -25
- metadata +12 -10
- data/.ruby-version +0 -1
- data/lib/bunny/compatibility.rb +0 -24
- data/spec/compatibility/queue_declare_spec.rb +0 -44
- data/spec/compatibility/queue_declare_with_default_channel_spec.rb +0 -33
data/lib/bunny/session.rb
CHANGED
@@ -82,9 +82,8 @@ module Bunny
|
|
82
82
|
|
83
83
|
# @return [Bunny::Transport]
|
84
84
|
attr_reader :transport
|
85
|
-
attr_reader :status, :
|
85
|
+
attr_reader :status, :port, :heartbeat, :user, :pass, :vhost, :frame_max, :channel_max, :threaded
|
86
86
|
attr_reader :server_capabilities, :server_properties, :server_authentication_mechanisms, :server_locales
|
87
|
-
attr_reader :default_channel
|
88
87
|
attr_reader :channel_id_allocator
|
89
88
|
# Authentication mechanism, e.g. "PLAIN" or "EXTERNAL"
|
90
89
|
# @return [String]
|
@@ -99,6 +98,7 @@ module Bunny
|
|
99
98
|
# @param [Hash] optz Extra options not related to connection
|
100
99
|
#
|
101
100
|
# @option connection_string_or_opts [String] :host ("127.0.0.1") Hostname or IP address to connect to
|
101
|
+
# @option connection_string_or_opts [Array<String>] :hosts (["127.0.0.1"]) list of hostname or IP addresses to select hostname from when connecting
|
102
102
|
# @option connection_string_or_opts [Integer] :port (5672) Port RabbitMQ listens on
|
103
103
|
# @option connection_string_or_opts [String] :username ("guest") Username
|
104
104
|
# @option connection_string_or_opts [String] :password ("guest") Password
|
@@ -109,8 +109,10 @@ module Bunny
|
|
109
109
|
# @option connection_string_or_opts [String] :tls_cert (nil) Path to client TLS/SSL certificate file (.pem)
|
110
110
|
# @option connection_string_or_opts [String] :tls_key (nil) Path to client TLS/SSL private key file (.pem)
|
111
111
|
# @option connection_string_or_opts [Array<String>] :tls_ca_certificates Array of paths to TLS/SSL CA files (.pem), by default detected from OpenSSL configuration
|
112
|
+
# @option connection_string_or_opts [String] :verify_peer (true) Whether TLS peer verification should be performed
|
112
113
|
# @option connection_string_or_opts [Integer] :continuation_timeout (4000) Timeout for client operations that expect a response (e.g. {Bunny::Queue#get}), in milliseconds.
|
113
114
|
# @option connection_string_or_opts [Integer] :connection_timeout (5) Timeout in seconds for connecting to the server.
|
115
|
+
# @option connection_string_or_opts [Proc] :hosts_shuffle_strategy A Proc that reorders a list of host strings, defaults to Array#shuffle
|
114
116
|
#
|
115
117
|
# @option optz [String] :auth_mechanism ("PLAIN") Authentication mechanism, PLAIN or EXTERNAL
|
116
118
|
# @option optz [String] :locale ("PLAIN") Locale RabbitMQ should use
|
@@ -128,8 +130,12 @@ module Bunny
|
|
128
130
|
connection_string_or_opts
|
129
131
|
end.merge(optz)
|
130
132
|
|
133
|
+
@default_hosts_shuffle_strategy = Proc.new { |hosts| hosts.shuffle }
|
134
|
+
|
131
135
|
@opts = opts
|
132
|
-
@
|
136
|
+
@hosts = self.hostnames_from(opts)
|
137
|
+
@host_index = 0
|
138
|
+
|
133
139
|
@port = self.port_from(opts)
|
134
140
|
@user = self.username_from(opts)
|
135
141
|
@pass = self.password_from(opts)
|
@@ -173,6 +179,8 @@ module Bunny
|
|
173
179
|
# the non-reentrant Ruby mutexes. MK.
|
174
180
|
@transport_mutex = @mutex_impl.new
|
175
181
|
@status_mutex = @mutex_impl.new
|
182
|
+
@host_index_mutex = @mutex_impl.new
|
183
|
+
|
176
184
|
@channels = Hash.new
|
177
185
|
|
178
186
|
@origin_thread = Thread.current
|
@@ -210,6 +218,14 @@ module Bunny
|
|
210
218
|
@threaded
|
211
219
|
end
|
212
220
|
|
221
|
+
def host
|
222
|
+
@transport ? @transport.host : @hosts[@host_index]
|
223
|
+
end
|
224
|
+
|
225
|
+
def reset_host_index
|
226
|
+
@host_index_mutex.synchronize { @host_index = 0 }
|
227
|
+
end
|
228
|
+
|
213
229
|
# @private
|
214
230
|
attr_reader :mutex_impl
|
215
231
|
|
@@ -232,6 +248,7 @@ module Bunny
|
|
232
248
|
# @see http://rubybunny.info/articles/connecting.html
|
233
249
|
# @api public
|
234
250
|
def start
|
251
|
+
|
235
252
|
return self if connected?
|
236
253
|
|
237
254
|
@status_mutex.synchronize { @status = :connecting }
|
@@ -241,27 +258,42 @@ module Bunny
|
|
241
258
|
self.reset_continuations
|
242
259
|
|
243
260
|
begin
|
244
|
-
# close existing transport if we have one,
|
245
|
-
# to not leak sockets
|
246
|
-
@transport.maybe_initialize_socket
|
247
261
|
|
248
|
-
|
249
|
-
@transport.connect
|
262
|
+
begin
|
250
263
|
|
251
|
-
|
252
|
-
|
253
|
-
|
264
|
+
# close existing transport if we have one,
|
265
|
+
# to not leak sockets
|
266
|
+
@transport.maybe_initialize_socket
|
254
267
|
|
255
|
-
|
256
|
-
|
268
|
+
@transport.post_initialize_socket
|
269
|
+
@transport.connect
|
257
270
|
|
258
|
-
|
259
|
-
|
271
|
+
if @socket_configurator
|
272
|
+
@transport.configure_socket(&@socket_configurator)
|
273
|
+
end
|
260
274
|
|
261
|
-
|
262
|
-
|
275
|
+
self.init_connection
|
276
|
+
self.open_connection
|
277
|
+
|
278
|
+
@reader_loop = nil
|
279
|
+
self.start_reader_loop if threaded?
|
280
|
+
|
281
|
+
rescue TCPConnectionFailed => e
|
282
|
+
self.initialize_transport
|
283
|
+
|
284
|
+
@logger.warn e.message
|
285
|
+
@logger.warn "Retrying connection on next host in line: #{@transport.host}:#{@transport.port}"
|
286
|
+
|
287
|
+
return self.start
|
288
|
+
rescue Exception
|
289
|
+
@status_mutex.synchronize { @status = :not_connected }
|
290
|
+
raise
|
291
|
+
end
|
292
|
+
|
293
|
+
rescue HostListDepleted
|
294
|
+
self.reset_host_index
|
263
295
|
@status_mutex.synchronize { @status = :not_connected }
|
264
|
-
raise
|
296
|
+
raise TCPConnectionFailedForAllHosts
|
265
297
|
end
|
266
298
|
|
267
299
|
self
|
@@ -355,40 +387,6 @@ module Bunny
|
|
355
387
|
@automatically_recover
|
356
388
|
end
|
357
389
|
|
358
|
-
#
|
359
|
-
# Backwards compatibility
|
360
|
-
#
|
361
|
-
|
362
|
-
# @private
|
363
|
-
def queue(*args)
|
364
|
-
@default_channel.queue(*args)
|
365
|
-
end
|
366
|
-
|
367
|
-
# @private
|
368
|
-
def direct(*args)
|
369
|
-
@default_channel.direct(*args)
|
370
|
-
end
|
371
|
-
|
372
|
-
# @private
|
373
|
-
def fanout(*args)
|
374
|
-
@default_channel.fanout(*args)
|
375
|
-
end
|
376
|
-
|
377
|
-
# @private
|
378
|
-
def topic(*args)
|
379
|
-
@default_channel.topic(*args)
|
380
|
-
end
|
381
|
-
|
382
|
-
# @private
|
383
|
-
def headers(*args)
|
384
|
-
@default_channel.headers(*args)
|
385
|
-
end
|
386
|
-
|
387
|
-
# @private
|
388
|
-
def exchange(*args)
|
389
|
-
@default_channel.exchange(*args)
|
390
|
-
end
|
391
|
-
|
392
390
|
# Defines a callback that will be executed when RabbitMQ blocks the connection
|
393
391
|
# because it is running low on memory or disk space (as configured via config file
|
394
392
|
# and/or rabbitmqctl).
|
@@ -646,6 +644,8 @@ module Bunny
|
|
646
644
|
begin
|
647
645
|
sleep @network_recovery_interval
|
648
646
|
@logger.debug "About to start connection recovery..."
|
647
|
+
|
648
|
+
self.reset_host_index # since we are starting a fresh try.
|
649
649
|
self.initialize_transport
|
650
650
|
self.start
|
651
651
|
|
@@ -654,7 +654,7 @@ module Bunny
|
|
654
654
|
|
655
655
|
recover_channels
|
656
656
|
end
|
657
|
-
rescue TCPConnectionFailed, AMQ::Protocol::EmptyResponseError => e
|
657
|
+
rescue TCPConnectionFailedForAllHosts, TCPConnectionFailed, AMQ::Protocol::EmptyResponseError => e
|
658
658
|
@logger.warn "TCP connection failed, reconnecting in #{@network_recovery_interval} seconds"
|
659
659
|
sleep @network_recovery_interval
|
660
660
|
retry if recoverable_network_failure?(e)
|
@@ -663,6 +663,9 @@ module Bunny
|
|
663
663
|
|
664
664
|
# @private
|
665
665
|
def recover_channels
|
666
|
+
# default channel is reopened right after connection
|
667
|
+
# negotiation is completed, so make sure we do not try to open
|
668
|
+
# it twice. MK.
|
666
669
|
@channels.each do |n, ch|
|
667
670
|
ch.open
|
668
671
|
|
@@ -726,8 +729,10 @@ module Bunny
|
|
726
729
|
end
|
727
730
|
|
728
731
|
# @private
|
729
|
-
def
|
730
|
-
options
|
732
|
+
def hostnames_from(options)
|
733
|
+
options.fetch(:hosts_shuffle_strategy, @default_hosts_shuffle_strategy).call(
|
734
|
+
[ options[:hosts] || options[:host] || options[:hostname] || DEFAULT_HOST ].flatten
|
735
|
+
)
|
731
736
|
end
|
732
737
|
|
733
738
|
# @private
|
@@ -923,7 +928,7 @@ module Bunny
|
|
923
928
|
# @return [String]
|
924
929
|
# @api public
|
925
930
|
def to_s
|
926
|
-
"#<#{self.class.name}:#{object_id} #{@user}@#{
|
931
|
+
"#<#{self.class.name}:#{object_id} #{@user}@#{host}:#{@port}, vhost=#{@vhost}, hosts=[#{@hosts.join(',')}]>"
|
927
932
|
end
|
928
933
|
|
929
934
|
protected
|
@@ -1076,7 +1081,12 @@ module Bunny
|
|
1076
1081
|
|
1077
1082
|
# @private
|
1078
1083
|
def initialize_transport
|
1079
|
-
|
1084
|
+
if host = @hosts[ @host_index ]
|
1085
|
+
@host_index_mutex.synchronize { @host_index += 1 }
|
1086
|
+
@transport = Transport.new(self, host, @port, @opts.merge(:session_thread => @origin_thread))
|
1087
|
+
else
|
1088
|
+
raise HostListDepleted
|
1089
|
+
end
|
1080
1090
|
end
|
1081
1091
|
|
1082
1092
|
# @private
|
data/lib/bunny/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
[rabbitmq_management, rabbitmq_consistent_hash_exchange].
|
@@ -0,0 +1,18 @@
|
|
1
|
+
[
|
2
|
+
|
3
|
+
{rabbit, [
|
4
|
+
{ssl_listeners, [5671]},
|
5
|
+
{ssl_options, [{cacertfile,"spec/tls/cacert.pem"},
|
6
|
+
{certfile,"spec/tls/server_cert.pem"},
|
7
|
+
{keyfile,"spec/tls/server_key.pem"},
|
8
|
+
{verify,verify_none},
|
9
|
+
{fail_if_no_peer_cert,false}]} ]
|
10
|
+
},
|
11
|
+
|
12
|
+
{rabbitmq_management,
|
13
|
+
[{listener,
|
14
|
+
[{port, 15672}]
|
15
|
+
}]
|
16
|
+
}
|
17
|
+
|
18
|
+
].
|
@@ -20,7 +20,7 @@ describe Bunny::Channel, "#ack" do
|
|
20
20
|
x.publish("bunneth", :routing_key => q.name)
|
21
21
|
sleep 0.5
|
22
22
|
q.message_count.should == 1
|
23
|
-
delivery_details, properties, content = q.pop(:
|
23
|
+
delivery_details, properties, content = q.pop(:manual_ack => true)
|
24
24
|
|
25
25
|
ch.ack(delivery_details.delivery_tag, true)
|
26
26
|
q.message_count.should == 0
|
@@ -57,7 +57,7 @@ describe Bunny::Channel, "#ack" do
|
|
57
57
|
x.publish("bunneth", :routing_key => q.name)
|
58
58
|
sleep 0.5
|
59
59
|
q.message_count.should == 1
|
60
|
-
_, _, content = q.pop(:
|
60
|
+
_, _, content = q.pop(:manual_ack => true)
|
61
61
|
|
62
62
|
ch.on_error do |ch, channel_close|
|
63
63
|
@channel_close = channel_close
|
@@ -68,4 +68,31 @@ describe Bunny::Channel, "#ack" do
|
|
68
68
|
@channel_close.reply_code.should == AMQ::Protocol::PreconditionFailed::VALUE
|
69
69
|
end
|
70
70
|
end
|
71
|
+
|
72
|
+
context "with a valid (known) delivery tag" do
|
73
|
+
it "gets a depricated message warning for using :ack" do
|
74
|
+
ch = connection.create_channel
|
75
|
+
q = ch.queue("bunny.basic.ack.manual-acks", :exclusive => true)
|
76
|
+
x = ch.default_exchange
|
77
|
+
|
78
|
+
x.publish("bunneth", :routing_key => q.name)
|
79
|
+
sleep 0.5
|
80
|
+
q.message_count.should == 1
|
81
|
+
|
82
|
+
orig_stderr = $stderr
|
83
|
+
$stderr = StringIO.new
|
84
|
+
|
85
|
+
delivery_details, properties, content = q.pop(:ack => true)
|
86
|
+
|
87
|
+
$stderr.rewind
|
88
|
+
$stderr.string.chomp.should eq("[DEPRECATION] `:ack` is deprecated. Please use `:manual_ack` instead.\n[DEPRECATION] `:ack` is deprecated. Please use `:manual_ack` instead.")
|
89
|
+
|
90
|
+
$stderr = orig_stderr
|
91
|
+
|
92
|
+
ch.ack(delivery_details.delivery_tag, true)
|
93
|
+
q.message_count.should == 0
|
94
|
+
|
95
|
+
ch.close
|
96
|
+
end
|
97
|
+
end
|
71
98
|
end
|
@@ -23,7 +23,7 @@ describe Bunny::Channel, "#nack" do
|
|
23
23
|
x.publish("bunneth", :routing_key => q.name)
|
24
24
|
sleep(0.5)
|
25
25
|
q.message_count.should == 1
|
26
|
-
delivery_info, _, content = q.pop(:
|
26
|
+
delivery_info, _, content = q.pop(:manual_ack => true)
|
27
27
|
|
28
28
|
subject.nack(delivery_info.delivery_tag, false, false)
|
29
29
|
sleep(0.5)
|
@@ -43,9 +43,9 @@ q = subject.queue("bunny.basic.nack.with-requeue-true-multi-true", :exclusive =>
|
|
43
43
|
end
|
44
44
|
sleep(0.5)
|
45
45
|
q.message_count.should == 3
|
46
|
-
_, _, _ = q.pop(:
|
47
|
-
_, _, _ = q.pop(:
|
48
|
-
delivery_info, _, content = q.pop(:
|
46
|
+
_, _, _ = q.pop(:manual_ack => true)
|
47
|
+
_, _, _ = q.pop(:manual_ack => true)
|
48
|
+
delivery_info, _, content = q.pop(:manual_ack => true)
|
49
49
|
|
50
50
|
subject.nack(delivery_info.delivery_tag, true, true)
|
51
51
|
sleep(0.5)
|
@@ -64,7 +64,7 @@ q = subject.queue("bunny.basic.nack.with-requeue-true-multi-true", :exclusive =>
|
|
64
64
|
x.publish("bunneth", :routing_key => q.name)
|
65
65
|
sleep(0.25)
|
66
66
|
q.message_count.should == 1
|
67
|
-
_, _, content = q.pop(:
|
67
|
+
_, _, content = q.pop(:manual_ack => true)
|
68
68
|
|
69
69
|
subject.on_error do |ch, channel_close|
|
70
70
|
@channel_close = channel_close
|
@@ -20,7 +20,7 @@ describe Bunny::Channel, "#reject" do
|
|
20
20
|
x.publish("bunneth", :routing_key => q.name)
|
21
21
|
sleep(0.5)
|
22
22
|
q.message_count.should == 1
|
23
|
-
delivery_info, _, _ = q.pop(:
|
23
|
+
delivery_info, _, _ = q.pop(:manual_ack => true)
|
24
24
|
|
25
25
|
ch.reject(delivery_info.delivery_tag, true)
|
26
26
|
sleep(0.5)
|
@@ -39,7 +39,7 @@ describe Bunny::Channel, "#reject" do
|
|
39
39
|
x.publish("bunneth", :routing_key => q.name)
|
40
40
|
sleep(0.5)
|
41
41
|
q.message_count.should == 1
|
42
|
-
delivery_info, _, _ = q.pop(:
|
42
|
+
delivery_info, _, _ = q.pop(:manual_ack => true)
|
43
43
|
|
44
44
|
ch.reject(delivery_info.delivery_tag, false)
|
45
45
|
sleep(0.5)
|
@@ -59,7 +59,7 @@ describe Bunny::Channel, "#reject" do
|
|
59
59
|
x.publish("bunneth", :routing_key => q.name)
|
60
60
|
sleep(0.25)
|
61
61
|
q.message_count.should == 1
|
62
|
-
_, _, content = q.pop(:
|
62
|
+
_, _, content = q.pop(:manual_ack => true)
|
63
63
|
|
64
64
|
ch.on_error do |ch, channel_close|
|
65
65
|
@channel_close = channel_close
|
@@ -8,7 +8,11 @@ unless ENV["CI"]
|
|
8
8
|
|
9
9
|
def close_all_connections!
|
10
10
|
http_client.list_connections.each do |conn_info|
|
11
|
-
|
11
|
+
begin
|
12
|
+
http_client.close_connection(conn_info.name)
|
13
|
+
rescue Bunny::ConnectionForced
|
14
|
+
# This is not a problem, but the specs intermittently believe it is.
|
15
|
+
end
|
12
16
|
end
|
13
17
|
end
|
14
18
|
|
@@ -25,6 +29,29 @@ unless ENV["CI"]
|
|
25
29
|
end
|
26
30
|
end
|
27
31
|
|
32
|
+
def with_open_multi_host( c = Bunny.new( :hosts => ["127.0.0.1", "localhost"],
|
33
|
+
:network_recovery_interval => 0.2,
|
34
|
+
:recover_from_connection_close => true), &block)
|
35
|
+
begin
|
36
|
+
c.start
|
37
|
+
block.call(c)
|
38
|
+
ensure
|
39
|
+
c.close
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def with_open_multi_broken_host( c = Bunny.new( :hosts => ["broken", "127.0.0.1", "localhost"],
|
44
|
+
:hosts_shuffle_strategy => Proc.new { |hosts| hosts }, # We do not shuffle for these tests so we always hit the broken host
|
45
|
+
:network_recovery_interval => 0.2,
|
46
|
+
:recover_from_connection_close => true), &block)
|
47
|
+
begin
|
48
|
+
c.start
|
49
|
+
block.call(c)
|
50
|
+
ensure
|
51
|
+
c.close
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
28
55
|
def ensure_queue_recovery(ch, q)
|
29
56
|
q.purge
|
30
57
|
x = ch.default_exchange
|
@@ -66,7 +93,29 @@ unless ENV["CI"]
|
|
66
93
|
end
|
67
94
|
end
|
68
95
|
|
69
|
-
it "
|
96
|
+
it "reconnects after grace period (with multiple hosts)" do
|
97
|
+
with_open_multi_host do |c|
|
98
|
+
close_all_connections!
|
99
|
+
sleep 0.1
|
100
|
+
c.should_not be_open
|
101
|
+
|
102
|
+
wait_for_recovery
|
103
|
+
c.should be_open
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it "reconnects after grace period (with multiple hosts, including a broken one)" do
|
108
|
+
with_open_multi_broken_host do |c|
|
109
|
+
close_all_connections!
|
110
|
+
sleep 0.1
|
111
|
+
c.should_not be_open
|
112
|
+
|
113
|
+
wait_for_recovery
|
114
|
+
c.should be_open
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it "recovers channels" do
|
70
119
|
with_open do |c|
|
71
120
|
ch1 = c.create_channel
|
72
121
|
ch2 = c.create_channel
|
@@ -80,6 +129,34 @@ unless ENV["CI"]
|
|
80
129
|
end
|
81
130
|
end
|
82
131
|
|
132
|
+
it "recovers channels (with multiple hosts)" do
|
133
|
+
with_open_multi_host do |c|
|
134
|
+
ch1 = c.create_channel
|
135
|
+
ch2 = c.create_channel
|
136
|
+
close_all_connections!
|
137
|
+
sleep 0.1
|
138
|
+
c.should_not be_open
|
139
|
+
|
140
|
+
wait_for_recovery
|
141
|
+
ch1.should be_open
|
142
|
+
ch2.should be_open
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
it "recovers channels (with multiple hosts, including a broken one)" do
|
147
|
+
with_open_multi_broken_host do |c|
|
148
|
+
ch1 = c.create_channel
|
149
|
+
ch2 = c.create_channel
|
150
|
+
close_all_connections!
|
151
|
+
sleep 0.1
|
152
|
+
c.should_not be_open
|
153
|
+
|
154
|
+
wait_for_recovery
|
155
|
+
ch1.should be_open
|
156
|
+
ch2.should be_open
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
83
160
|
it "recovers basic.qos prefetch setting" do
|
84
161
|
with_open do |c|
|
85
162
|
ch = c.create_channel
|