bunny 1.7.0 → 2.17.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.
Files changed (141) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE.md +18 -0
  3. data/.gitignore +6 -1
  4. data/.rspec +1 -3
  5. data/.travis.yml +21 -14
  6. data/CONTRIBUTING.md +132 -0
  7. data/ChangeLog.md +745 -1
  8. data/Gemfile +13 -13
  9. data/LICENSE +1 -1
  10. data/README.md +41 -75
  11. data/Rakefile +54 -0
  12. data/bunny.gemspec +4 -10
  13. data/docker-compose.yml +28 -0
  14. data/docker/Dockerfile +24 -0
  15. data/docker/apt/preferences.d/erlang +3 -0
  16. data/docker/apt/sources.list.d/bintray.rabbitmq.list +2 -0
  17. data/docker/docker-entrypoint.sh +26 -0
  18. data/docker/rabbitmq.conf +29 -0
  19. data/examples/connection/automatic_recovery_with_basic_get.rb +1 -1
  20. data/examples/connection/automatic_recovery_with_client_named_queues.rb +1 -1
  21. data/examples/connection/automatic_recovery_with_multiple_consumers.rb +1 -1
  22. data/examples/connection/automatic_recovery_with_republishing.rb +1 -1
  23. data/examples/connection/automatic_recovery_with_server_named_queues.rb +1 -1
  24. data/examples/connection/channel_level_exception.rb +1 -9
  25. data/examples/connection/disabled_automatic_recovery.rb +1 -1
  26. data/examples/connection/heartbeat.rb +1 -1
  27. data/examples/consumers/high_and_low_priority.rb +1 -1
  28. data/examples/guides/extensions/alternate_exchange.rb +2 -0
  29. data/examples/guides/getting_started/hello_world.rb +2 -0
  30. data/examples/guides/getting_started/weathr.rb +2 -0
  31. data/examples/guides/queues/one_off_consumer.rb +2 -0
  32. data/examples/guides/queues/redeliveries.rb +2 -0
  33. data/lib/bunny.rb +6 -2
  34. data/lib/bunny/channel.rb +192 -109
  35. data/lib/bunny/channel_id_allocator.rb +6 -4
  36. data/lib/bunny/concurrent/continuation_queue.rb +34 -13
  37. data/lib/bunny/consumer_work_pool.rb +34 -6
  38. data/lib/bunny/cruby/socket.rb +29 -16
  39. data/lib/bunny/cruby/ssl_socket.rb +20 -7
  40. data/lib/bunny/exceptions.rb +7 -1
  41. data/lib/bunny/exchange.rb +11 -7
  42. data/lib/bunny/get_response.rb +1 -1
  43. data/lib/bunny/heartbeat_sender.rb +3 -2
  44. data/lib/bunny/jruby/socket.rb +23 -6
  45. data/lib/bunny/jruby/ssl_socket.rb +5 -0
  46. data/lib/bunny/queue.rb +12 -10
  47. data/lib/bunny/reader_loop.rb +31 -18
  48. data/lib/bunny/session.rb +389 -134
  49. data/lib/bunny/test_kit.rb +14 -0
  50. data/lib/bunny/timeout.rb +1 -12
  51. data/lib/bunny/transport.rb +114 -67
  52. data/lib/bunny/version.rb +1 -1
  53. data/repl +1 -1
  54. data/spec/config/rabbitmq.conf +13 -0
  55. data/spec/higher_level_api/integration/basic_ack_spec.rb +154 -22
  56. data/spec/higher_level_api/integration/basic_cancel_spec.rb +77 -11
  57. data/spec/higher_level_api/integration/basic_consume_spec.rb +60 -55
  58. data/spec/higher_level_api/integration/basic_consume_with_objects_spec.rb +6 -6
  59. data/spec/higher_level_api/integration/basic_get_spec.rb +31 -7
  60. data/spec/higher_level_api/integration/basic_nack_spec.rb +22 -19
  61. data/spec/higher_level_api/integration/basic_publish_spec.rb +11 -100
  62. data/spec/higher_level_api/integration/basic_qos_spec.rb +32 -4
  63. data/spec/higher_level_api/integration/basic_reject_spec.rb +94 -16
  64. data/spec/higher_level_api/integration/basic_return_spec.rb +4 -4
  65. data/spec/higher_level_api/integration/channel_close_spec.rb +51 -10
  66. data/spec/higher_level_api/integration/channel_open_spec.rb +12 -12
  67. data/spec/higher_level_api/integration/connection_recovery_spec.rb +412 -286
  68. data/spec/higher_level_api/integration/connection_spec.rb +284 -134
  69. data/spec/higher_level_api/integration/connection_stop_spec.rb +31 -19
  70. data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +17 -17
  71. data/spec/higher_level_api/integration/dead_lettering_spec.rb +14 -14
  72. data/spec/higher_level_api/integration/exchange_bind_spec.rb +5 -5
  73. data/spec/higher_level_api/integration/exchange_declare_spec.rb +32 -31
  74. data/spec/higher_level_api/integration/exchange_delete_spec.rb +12 -12
  75. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +5 -5
  76. data/spec/higher_level_api/integration/exclusive_queue_spec.rb +5 -5
  77. data/spec/higher_level_api/integration/heartbeat_spec.rb +4 -4
  78. data/spec/higher_level_api/integration/message_properties_access_spec.rb +49 -49
  79. data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +2 -2
  80. data/spec/higher_level_api/integration/publisher_confirms_spec.rb +92 -27
  81. data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +19 -19
  82. data/spec/higher_level_api/integration/queue_bind_spec.rb +23 -23
  83. data/spec/higher_level_api/integration/queue_declare_spec.rb +129 -34
  84. data/spec/higher_level_api/integration/queue_delete_spec.rb +2 -2
  85. data/spec/higher_level_api/integration/queue_purge_spec.rb +5 -5
  86. data/spec/higher_level_api/integration/queue_unbind_spec.rb +6 -6
  87. data/spec/higher_level_api/integration/read_only_consumer_spec.rb +9 -9
  88. data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +10 -10
  89. data/spec/higher_level_api/integration/tls_connection_spec.rb +218 -112
  90. data/spec/higher_level_api/integration/toxiproxy_spec.rb +76 -0
  91. data/spec/higher_level_api/integration/tx_commit_spec.rb +1 -1
  92. data/spec/higher_level_api/integration/tx_rollback_spec.rb +1 -1
  93. data/spec/higher_level_api/integration/with_channel_spec.rb +2 -2
  94. data/spec/issues/issue100_spec.rb +11 -12
  95. data/spec/issues/issue141_spec.rb +13 -14
  96. data/spec/issues/issue202_spec.rb +1 -1
  97. data/spec/issues/issue224_spec.rb +5 -5
  98. data/spec/issues/issue465_spec.rb +32 -0
  99. data/spec/issues/issue549_spec.rb +30 -0
  100. data/spec/issues/issue78_spec.rb +21 -24
  101. data/spec/issues/issue83_spec.rb +5 -6
  102. data/spec/issues/issue97_spec.rb +44 -45
  103. data/spec/lower_level_api/integration/basic_cancel_spec.rb +15 -16
  104. data/spec/lower_level_api/integration/basic_consume_spec.rb +20 -21
  105. data/spec/spec_helper.rb +2 -19
  106. data/spec/stress/channel_close_stress_spec.rb +3 -3
  107. data/spec/stress/channel_open_stress_spec.rb +4 -4
  108. data/spec/stress/channel_open_stress_with_single_threaded_connection_spec.rb +7 -7
  109. data/spec/stress/concurrent_consumers_stress_spec.rb +18 -16
  110. data/spec/stress/concurrent_publishers_stress_spec.rb +16 -19
  111. data/spec/stress/connection_open_close_spec.rb +9 -9
  112. data/spec/stress/merry_go_round_spec.rb +105 -0
  113. data/spec/tls/ca_certificate.pem +27 -16
  114. data/spec/tls/ca_key.pem +52 -27
  115. data/spec/tls/client_certificate.pem +27 -16
  116. data/spec/tls/client_key.pem +49 -25
  117. data/spec/tls/generate-server-cert.sh +8 -0
  118. data/spec/tls/server-openssl.cnf +10 -0
  119. data/spec/tls/server.csr +16 -0
  120. data/spec/tls/server_certificate.pem +27 -16
  121. data/spec/tls/server_key.pem +49 -25
  122. data/spec/toxiproxy_helper.rb +28 -0
  123. data/spec/unit/bunny_spec.rb +5 -5
  124. data/spec/unit/concurrent/atomic_fixnum_spec.rb +6 -6
  125. data/spec/unit/concurrent/condition_spec.rb +8 -8
  126. data/spec/unit/concurrent/linked_continuation_queue_spec.rb +2 -2
  127. data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +16 -16
  128. data/spec/unit/exchange_recovery_spec.rb +39 -0
  129. data/spec/unit/version_delivery_tag_spec.rb +3 -3
  130. metadata +42 -35
  131. data/lib/bunny/system_timer.rb +0 -20
  132. data/spec/config/rabbitmq.config +0 -18
  133. data/spec/higher_level_api/integration/basic_recover_spec.rb +0 -18
  134. data/spec/higher_level_api/integration/confirm_select_spec.rb +0 -19
  135. data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +0 -50
  136. data/spec/higher_level_api/integration/merry_go_round_spec.rb +0 -85
  137. data/spec/stress/long_running_consumer_spec.rb +0 -83
  138. data/spec/tls/cacert.pem +0 -18
  139. data/spec/tls/client_cert.pem +0 -18
  140. data/spec/tls/server_cert.pem +0 -18
  141. data/spec/unit/system_timer_spec.rb +0 -10
@@ -1,27 +1,26 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Bunny::Channel, "#basic_cancel" do
4
- let(:connection) do
5
- c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
6
- c.start
7
- c
4
+ before(:all) do
5
+ @connection = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
6
+ @connection.start
8
7
  end
9
8
 
10
9
  after :all do
11
- connection.close if connection.open?
10
+ @connection.close if @connection.open?
12
11
  end
13
12
 
14
13
  let(:queue_name) { "bunny.queues.#{rand}" }
15
14
 
16
15
  it "returns basic.cancel-ok" do
17
- ch = connection.create_channel
16
+ ch = @connection.create_channel
18
17
  q = ch.queue("", :exclusive => true)
19
18
 
20
19
  consume_ok = ch.basic_consume(q, "")
21
20
  cancel_ok = ch.basic_cancel(consume_ok.consumer_tag)
22
21
 
23
- cancel_ok.should be_instance_of(AMQ::Protocol::Basic::CancelOk)
24
- cancel_ok.consumer_tag.should == consume_ok.consumer_tag
22
+ expect(cancel_ok).to be_instance_of AMQ::Protocol::Basic::CancelOk
23
+ expect(cancel_ok.consumer_tag).to eq consume_ok.consumer_tag
25
24
 
26
25
  ch.close
27
26
  end
@@ -33,32 +32,32 @@ describe Bunny::Channel, "#basic_cancel" do
33
32
  delivered_data = []
34
33
 
35
34
  t = Thread.new do
36
- ch = connection.create_channel
35
+ ch = @connection.create_channel
37
36
  q = ch.queue(queue_name, :auto_delete => true, :durable => false)
38
37
  consume_ok = ch.basic_consume(q, "", true, false) do |_, _, payload|
39
38
  delivered_data << payload
40
39
  end
41
40
 
42
- consume_ok.consumer_tag.should_not be_nil
41
+ expect(consume_ok.consumer_tag).not_to be_nil
43
42
  cancel_ok = ch.basic_cancel(consume_ok.consumer_tag)
44
- cancel_ok.consumer_tag.should == consume_ok.consumer_tag
43
+ expect(cancel_ok.consumer_tag).to eq consume_ok.consumer_tag
45
44
 
46
45
  ch.close
47
46
  end
48
47
  t.abort_on_exception = true
49
48
  sleep 0.5
50
49
 
51
- ch = connection.create_channel
50
+ ch = @connection.create_channel
52
51
  ch.default_exchange.publish("", :routing_key => queue_name)
53
52
 
54
53
  sleep 0.7
55
- delivered_data.should be_empty
54
+ expect(delivered_data).to be_empty
56
55
  end
57
56
  end
58
57
 
59
58
  context "when the given consumer tag is invalid (was never registered)" do
60
59
  it "DOES NOT cause a channel error" do
61
- ch = connection.create_channel
60
+ ch = @connection.create_channel
62
61
 
63
62
  # RabbitMQ 3.1 does not raise an exception w/ unknown consumer tag. MK.
64
63
  ch.basic_cancel("878798s7df89#{rand}#{Time.now.to_i}")
@@ -69,8 +68,8 @@ describe Bunny::Channel, "#basic_cancel" do
69
68
 
70
69
  context "when the given consumer tag belongs to a different channel" do
71
70
  it "DOES NOT cause a channel error" do
72
- ch1 = connection.create_channel
73
- ch2 = connection.create_channel
71
+ ch1 = @connection.create_channel
72
+ ch2 = @connection.create_channel
74
73
 
75
74
  q = ch1.queue("", :exclusive => true)
76
75
  cons = q.subscribe do |_, _, _|
@@ -1,33 +1,32 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Bunny::Channel, "#basic_consume" do
4
- let(:connection) do
5
- c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
6
- c.start
7
- c
4
+ before(:all) do
5
+ @connection = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
6
+ @connection.start
8
7
  end
9
8
 
10
9
  after :all do
11
- connection.close if connection.open?
10
+ @connection.close if @connection.open?
12
11
  end
13
12
 
14
13
  it "returns basic.consume-ok when it is received" do
15
- ch = connection.create_channel
14
+ ch = @connection.create_channel
16
15
  q = ch.queue("", :exclusive => true)
17
16
 
18
17
  consume_ok = ch.basic_consume(q)
19
- consume_ok.should be_instance_of(AMQ::Protocol::Basic::ConsumeOk)
20
- consume_ok.consumer_tag.should_not be_nil
18
+ expect(consume_ok).to be_instance_of AMQ::Protocol::Basic::ConsumeOk
19
+ expect(consume_ok.consumer_tag).not_to be_nil
21
20
 
22
21
  ch.close
23
22
  end
24
23
 
25
24
  it "carries server-generated consumer tag with basic.consume-ok" do
26
- ch = connection.create_channel
25
+ ch = @connection.create_channel
27
26
  q = ch.queue("", :exclusive => true)
28
27
 
29
28
  consume_ok = ch.basic_consume(q, "")
30
- consume_ok.consumer_tag.should =~ /amq\.ctag.*/
29
+ expect(consume_ok.consumer_tag).to match /amq\.ctag.*/
31
30
 
32
31
  ch.close
33
32
  end
@@ -40,7 +39,7 @@ describe Bunny::Channel, "#basic_consume" do
40
39
  delivered_data = []
41
40
 
42
41
  t = Thread.new do
43
- ch = connection.create_channel
42
+ ch = @connection.create_channel
44
43
  q = ch.queue(queue_name, :auto_delete => true, :durable => false)
45
44
  ch.basic_consume(q, "", true, false) do |delivery_info, properties, payload|
46
45
  delivered_keys << delivery_info.routing_key
@@ -50,15 +49,15 @@ describe Bunny::Channel, "#basic_consume" do
50
49
  t.abort_on_exception = true
51
50
  sleep 0.5
52
51
 
53
- ch = connection.create_channel
52
+ ch = @connection.create_channel
54
53
  x = ch.default_exchange
55
54
  x.publish("hello", :routing_key => queue_name)
56
55
 
57
56
  sleep 0.7
58
- delivered_keys.should include(queue_name)
59
- delivered_data.should include("hello")
57
+ expect(delivered_keys).to include queue_name
58
+ expect(delivered_data).to include "hello"
60
59
 
61
- ch.queue(queue_name, :auto_delete => true, :durable => false).message_count.should == 0
60
+ expect(ch.queue(queue_name, :auto_delete => true, :durable => false).message_count).to eq 0
62
61
 
63
62
  ch.close
64
63
  end
@@ -72,7 +71,7 @@ describe Bunny::Channel, "#basic_consume" do
72
71
  delivered_data = []
73
72
 
74
73
  t = Thread.new do
75
- ch = connection.create_channel
74
+ ch = @connection.create_channel
76
75
  q = ch.queue(queue_name, :auto_delete => true, :durable => false)
77
76
  ch.basic_consume(q, "", false, false) do |delivery_info, properties, payload|
78
77
  delivered_keys << delivery_info.routing_key
@@ -84,17 +83,17 @@ describe Bunny::Channel, "#basic_consume" do
84
83
  t.abort_on_exception = true
85
84
  sleep 0.5
86
85
 
87
- ch = connection.create_channel
86
+ ch = @connection.create_channel
88
87
  x = ch.default_exchange
89
88
  x.publish("hello", :routing_key => queue_name)
90
89
 
91
90
  sleep 0.7
92
- delivered_keys.should include(queue_name)
93
- delivered_data.should include("hello")
91
+ expect(delivered_keys).to include queue_name
92
+ expect(delivered_data).to include "hello"
94
93
 
95
- ch.queue(queue_name, :auto_delete => true, :durable => false).message_count.should == 0
94
+ expect(ch.queue(queue_name, :auto_delete => true, :durable => false).message_count).to eq 0
96
95
 
97
- ch.close
96
+ ch.close
98
97
  end
99
98
  end
100
99
  end
@@ -3,30 +3,13 @@
3
3
  $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
4
4
 
5
5
  require 'bundler'
6
- Bundler.setup(:default, :test)
6
+ Bundler.require(:default, :test)
7
7
 
8
-
9
- require "effin_utf8"
10
8
  require "bunny"
11
- require "rabbitmq/http/client"
12
-
9
+ require "bunny/test_kit"
13
10
 
14
- require "amq/protocol/version"
15
11
  puts "Using Ruby #{RUBY_VERSION}, amq-protocol #{AMQ::Protocol::VERSION}"
16
12
 
17
- #
18
- # Ruby version-specific
19
- #
20
-
21
- case RUBY_VERSION
22
- when "1.8.7" then
23
- class Array
24
- alias sample choice
25
- end
26
- when "1.8.6" then
27
- raise "Ruby 1.8.6 is not supported. Sorry, pal. Time to move on beyond One True Ruby. Yes, time flies by."
28
- end
29
-
30
13
  module RabbitMQ
31
14
  module Control
32
15
 
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe "Rapidly closing lots of temporary channels" do
4
4
  before :all do
5
- @connection = Bunny.new(:automatic_recovery => false).tap do |c|
5
+ @connection = Bunny.new(automatic_recovery: false).tap do |c|
6
6
  c.start
7
7
  end
8
8
  end
@@ -21,7 +21,7 @@ describe "Rapidly closing lots of temporary channels" do
21
21
  n.times do
22
22
  t = Thread.new do
23
23
  @connection.with_channel do |ch1|
24
- q = ch1.queue("", :exclusive => true)
24
+ q = ch1.queue("", exclusive: true)
25
25
  q.delete
26
26
  ch1.close
27
27
  end
@@ -49,7 +49,7 @@ describe "Rapidly closing lots of temporary channels" do
49
49
  t = Thread.new do
50
50
  3.times do
51
51
  @connection.with_channel do |ch|
52
- x = ch.topic('bunny.stress.topics.t2', :durable => false)
52
+ x = ch.topic('bunny.stress.topics.t2', durable: false)
53
53
  end
54
54
  end
55
55
  end
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe "Rapidly opening and closing lots of channels" do
4
4
  before :all do
5
- @connection = Bunny.new(:automatic_recovery => false).tap do |c|
5
+ @connection = Bunny.new(automatic_recovery: false).tap do |c|
6
6
  c.start
7
7
  end
8
8
  end
@@ -18,7 +18,7 @@ describe "Rapidly opening and closing lots of channels" do
18
18
  xs = Array.new(n) { @connection.create_channel }
19
19
  puts "Opened #{n} channels"
20
20
 
21
- xs.size.should == n
21
+ expect(xs.size).to eq n
22
22
  xs.each do |ch|
23
23
  ch.close
24
24
  end
@@ -42,7 +42,7 @@ describe "Rapidly opening and closing lots of channels" do
42
42
  n.times do
43
43
  t = Thread.new do
44
44
  ch1 = @connection.create_channel
45
- q = ch1.queue("", :exclusive => true)
45
+ q = ch1.queue("", exclusive: true)
46
46
  q.delete
47
47
  ch1.close
48
48
 
@@ -69,7 +69,7 @@ describe "Rapidly opening and closing lots of channels" do
69
69
  t = Thread.new do
70
70
  3.times do
71
71
  ch = @connection.create_channel
72
- x = ch.topic('bunny.stress.topics.t2', :durable => false)
72
+ x = ch.topic('bunny.stress.topics.t2', durable: false)
73
73
  ch.close
74
74
  end
75
75
  end
@@ -2,23 +2,23 @@ require "spec_helper"
2
2
 
3
3
  unless ENV["CI"]
4
4
  describe "Rapidly opening and closing lots of channels on a non-threaded connection" do
5
- let(:connection) do
6
- c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed", :automatic_recovery => false, :threaded => false)
7
- c.start
8
- c
5
+ before :all do
6
+ @connection = Bunny.new(username: "bunny_gem", password: "bunny_password", vhost: "bunny_testbed",
7
+ automatic_recovery: false, threaded: false)
8
+ @connection.start
9
9
  end
10
10
 
11
11
  after :all do
12
- connection.close
12
+ @connection.close
13
13
  end
14
14
 
15
15
  context "in a single-threaded scenario" do
16
16
  let(:n) { 500 }
17
17
 
18
18
  it "works correctly" do
19
- xs = Array.new(n) { connection.create_channel }
19
+ xs = Array.new(n) { @connection.create_channel }
20
20
 
21
- xs.size.should == n
21
+ expect(xs.size).to eq n
22
22
  xs.each do |ch|
23
23
  ch.close
24
24
  end
@@ -3,15 +3,14 @@ require "spec_helper"
3
3
 
4
4
  unless ENV["CI"]
5
5
  describe "Concurrent consumers sharing a connection" do
6
- let(:connection) do
7
- c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed",
8
- :automatic_recovery => false, :continuation_timeout => 6000)
9
- c.start
10
- c
6
+ before :all do
7
+ @connection = Bunny.new(username: "bunny_gem", password: "bunny_password", vhost: "bunny_testbed",
8
+ automatic_recovery: false, continuation_timeout: 45000)
9
+ @connection.start
11
10
  end
12
11
 
13
12
  after :all do
14
- connection.close
13
+ @connection.close
15
14
  end
16
15
 
17
16
  def any_not_drained?(qs)
@@ -21,17 +20,18 @@ unless ENV["CI"]
21
20
  context "when publishing thousands of messages over 128K in size" do
22
21
  let(:colors) { ["red", "blue", "white"] }
23
22
 
24
- let(:n) { 32 }
25
- let(:m) { 1000 }
23
+ let(:n) { 16 }
24
+ let(:m) { 5000 }
26
25
 
27
26
  it "successfully drain all queues" do
28
- ch = connection.create_channel
27
+ ch0 = @connection.create_channel
28
+ ch0.confirm_select
29
29
  body = "абвг"
30
- x = ch.topic("bunny.stress.concurrent.consumers.topic", :durable => true)
30
+ x = ch0.topic("bunny.stress.concurrent.consumers.topic", durable: true)
31
31
 
32
32
  chs = {}
33
33
  n.times do |i|
34
- chs[i] = connection.create_channel
34
+ chs[i] = @connection.create_channel
35
35
  end
36
36
  qs = []
37
37
 
@@ -39,8 +39,8 @@ unless ENV["CI"]
39
39
  t = Thread.new do
40
40
  cht = chs[i]
41
41
 
42
- q = cht.queue("", :exclusive => true)
43
- q.bind(x.name, :routing_key => colors.sample).subscribe do |delivery_info, meta, payload|
42
+ q = cht.queue("", exclusive: true)
43
+ q.bind(x.name, routing_key: colors.sample).subscribe do |delivery_info, meta, payload|
44
44
  # no-op
45
45
  end
46
46
  qs << q
@@ -52,17 +52,19 @@ unless ENV["CI"]
52
52
 
53
53
  5.times do |i|
54
54
  m.times do
55
- x.publish(body, :routing_key => colors.sample)
55
+ x.publish(body, routing_key: colors.sample)
56
56
  end
57
57
  puts "Published #{(i + 1) * m} messages..."
58
+ ch0.wait_for_confirms
58
59
  end
59
60
 
60
61
  while any_not_drained?(qs)
61
62
  sleep 1.0
62
63
  end
63
- puts "Drained all the queues..."
64
+ puts "Drained all queues, winding down..."
64
65
 
65
- ch.close
66
+ ch0.close
67
+ chs.each { |_, ch| ch.close }
66
68
  end
67
69
  end
68
70
  end
@@ -3,31 +3,27 @@ require "spec_helper"
3
3
 
4
4
  unless ENV["CI"]
5
5
  describe "Concurrent publishers sharing a connection" do
6
- let(:connection) do
7
- c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed", :automatically_recover => false, :continuation_timeout => 20.0)
8
- c.start
9
- c
6
+ before :all do
7
+ @connection = Bunny.new(username: "bunny_gem", password: "bunny_password",
8
+ vhost: "bunny_testbed", automatically_recover: false)
9
+ @connection.start
10
10
  end
11
11
 
12
12
  after :all do
13
- connection.close
13
+ @connection.close
14
14
  end
15
15
 
16
16
  let(:concurrency) { 24 }
17
- let(:rate) { 5_000 }
17
+ let(:messages) { 5_000 }
18
18
 
19
19
  it "successfully finish publishing" do
20
- ch = connection.create_channel
21
-
22
- q = ch.queue("", :exclusive => true)
23
20
  body = "сообщение"
24
21
 
25
- # let the queue name be sent back by RabbitMQ
26
- sleep 0.25
27
-
28
22
  chs = {}
29
23
  concurrency.times do |i|
30
- chs[i] = connection.create_channel
24
+ ch = @connection.create_channel
25
+ ch.confirm_select
26
+ chs[i] = ch
31
27
  end
32
28
 
33
29
  ts = []
@@ -35,14 +31,13 @@ unless ENV["CI"]
35
31
  concurrency.times do |i|
36
32
  t = Thread.new do
37
33
  cht = chs[i]
38
- x = ch.default_exchange
34
+ x = cht.default_exchange
39
35
 
40
- 5.times do |i|
41
- rate.times do
42
- x.publish(body, :routing_key => q.name)
43
- end
44
- puts "Published #{(i + 1) * rate} messages..."
36
+ messages.times do
37
+ x.publish(body)
45
38
  end
39
+ puts "Published #{messages} messages..."
40
+ cht.wait_for_confirms
46
41
  end
47
42
  t.abort_on_exception = true
48
43
 
@@ -52,6 +47,8 @@ unless ENV["CI"]
52
47
  ts.each do |t|
53
48
  t.join
54
49
  end
50
+
51
+ chs.each { |_, ch| ch.close }
55
52
  end
56
53
  end
57
54
  end