bunny 2.19.0 → 2.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -32
  3. data/lib/bunny/channel.rb +86 -10
  4. data/lib/bunny/consumer.rb +2 -2
  5. data/lib/bunny/delivery_info.rb +1 -1
  6. data/lib/bunny/queue.rb +33 -2
  7. data/lib/bunny/session.rb +1 -1
  8. data/lib/bunny/transport.rb +30 -1
  9. data/lib/bunny/version.rb +1 -1
  10. data/lib/bunny.rb +45 -4
  11. metadata +4 -144
  12. data/spec/config/enabled_plugins +0 -1
  13. data/spec/config/rabbitmq.conf +0 -13
  14. data/spec/higher_level_api/integration/basic_ack_spec.rb +0 -230
  15. data/spec/higher_level_api/integration/basic_cancel_spec.rb +0 -142
  16. data/spec/higher_level_api/integration/basic_consume_spec.rb +0 -357
  17. data/spec/higher_level_api/integration/basic_consume_with_objects_spec.rb +0 -54
  18. data/spec/higher_level_api/integration/basic_get_spec.rb +0 -80
  19. data/spec/higher_level_api/integration/basic_nack_spec.rb +0 -82
  20. data/spec/higher_level_api/integration/basic_publish_spec.rb +0 -74
  21. data/spec/higher_level_api/integration/basic_qos_spec.rb +0 -57
  22. data/spec/higher_level_api/integration/basic_reject_spec.rb +0 -152
  23. data/spec/higher_level_api/integration/basic_return_spec.rb +0 -33
  24. data/spec/higher_level_api/integration/channel_close_spec.rb +0 -66
  25. data/spec/higher_level_api/integration/channel_open_spec.rb +0 -57
  26. data/spec/higher_level_api/integration/connection_recovery_spec.rb +0 -483
  27. data/spec/higher_level_api/integration/connection_spec.rb +0 -589
  28. data/spec/higher_level_api/integration/connection_stop_spec.rb +0 -83
  29. data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +0 -128
  30. data/spec/higher_level_api/integration/dead_lettering_spec.rb +0 -75
  31. data/spec/higher_level_api/integration/exchange_bind_spec.rb +0 -31
  32. data/spec/higher_level_api/integration/exchange_declare_spec.rb +0 -237
  33. data/spec/higher_level_api/integration/exchange_delete_spec.rb +0 -105
  34. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +0 -40
  35. data/spec/higher_level_api/integration/exclusive_queue_spec.rb +0 -28
  36. data/spec/higher_level_api/integration/heartbeat_spec.rb +0 -49
  37. data/spec/higher_level_api/integration/message_properties_access_spec.rb +0 -95
  38. data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +0 -24
  39. data/spec/higher_level_api/integration/publisher_confirms_spec.rb +0 -191
  40. data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +0 -87
  41. data/spec/higher_level_api/integration/queue_bind_spec.rb +0 -109
  42. data/spec/higher_level_api/integration/queue_declare_spec.rb +0 -285
  43. data/spec/higher_level_api/integration/queue_delete_spec.rb +0 -41
  44. data/spec/higher_level_api/integration/queue_purge_spec.rb +0 -30
  45. data/spec/higher_level_api/integration/queue_unbind_spec.rb +0 -54
  46. data/spec/higher_level_api/integration/read_only_consumer_spec.rb +0 -60
  47. data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +0 -36
  48. data/spec/higher_level_api/integration/tls_connection_spec.rb +0 -255
  49. data/spec/higher_level_api/integration/toxiproxy_spec.rb +0 -76
  50. data/spec/higher_level_api/integration/tx_commit_spec.rb +0 -21
  51. data/spec/higher_level_api/integration/tx_rollback_spec.rb +0 -21
  52. data/spec/higher_level_api/integration/with_channel_spec.rb +0 -25
  53. data/spec/issues/issue100_spec.rb +0 -42
  54. data/spec/issues/issue141_spec.rb +0 -43
  55. data/spec/issues/issue202_spec.rb +0 -15
  56. data/spec/issues/issue224_spec.rb +0 -40
  57. data/spec/issues/issue465_spec.rb +0 -32
  58. data/spec/issues/issue549_spec.rb +0 -30
  59. data/spec/issues/issue609_spec.rb +0 -84
  60. data/spec/issues/issue78_spec.rb +0 -72
  61. data/spec/issues/issue83_spec.rb +0 -30
  62. data/spec/issues/issue97_attachment.json +0 -1
  63. data/spec/issues/issue97_spec.rb +0 -175
  64. data/spec/lower_level_api/integration/basic_cancel_spec.rb +0 -83
  65. data/spec/lower_level_api/integration/basic_consume_spec.rb +0 -99
  66. data/spec/spec_helper.rb +0 -47
  67. data/spec/stress/channel_close_stress_spec.rb +0 -64
  68. data/spec/stress/channel_open_stress_spec.rb +0 -84
  69. data/spec/stress/channel_open_stress_with_single_threaded_connection_spec.rb +0 -28
  70. data/spec/stress/concurrent_consumers_stress_spec.rb +0 -71
  71. data/spec/stress/concurrent_publishers_stress_spec.rb +0 -54
  72. data/spec/stress/connection_open_close_spec.rb +0 -52
  73. data/spec/stress/merry_go_round_spec.rb +0 -105
  74. data/spec/toxiproxy_helper.rb +0 -28
  75. data/spec/unit/bunny_spec.rb +0 -15
  76. data/spec/unit/concurrent/atomic_fixnum_spec.rb +0 -35
  77. data/spec/unit/concurrent/condition_spec.rb +0 -82
  78. data/spec/unit/concurrent/linked_continuation_queue_spec.rb +0 -35
  79. data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +0 -73
  80. data/spec/unit/exchange_recovery_spec.rb +0 -39
  81. data/spec/unit/version_delivery_tag_spec.rb +0 -28
@@ -1,175 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "Message framing implementation" do
4
- before :all do
5
- @connection = Bunny.new(username: "bunny_gem",
6
- password: "bunny_password",
7
- vhost: "bunny_testbed",
8
- port: ENV.fetch("RABBITMQ_PORT", 5672))
9
- @connection.start
10
- end
11
-
12
- after :all do
13
- @connection.close if @connection.open?
14
- end
15
-
16
-
17
- unless ENV["CI"]
18
- context "with payload ~ 248K in size including non-ASCII characters" do
19
- it "successfully frames the message" do
20
- ch = @connection.create_channel
21
-
22
- q = ch.queue("", exclusive: true)
23
- x = ch.default_exchange
24
-
25
- body = IO.read("spec/issues/issue97_attachment.json")
26
- x.publish(body, routing_key: q.name, persistent: true)
27
-
28
- sleep(1)
29
- expect(q.message_count).to eq 1
30
-
31
- q.purge
32
- ch.close
33
- end
34
- end
35
- end
36
-
37
-
38
- context "with payload of several MBs in size" do
39
- it "successfully frames the message" do
40
- ch = @connection.create_channel
41
-
42
- q = ch.queue("", exclusive: true)
43
- x = ch.default_exchange
44
-
45
- as = ("a" * (1024 * 1024 * 4 + 2823777))
46
- x.publish(as, routing_key: q.name, persistent: true)
47
-
48
- sleep(1)
49
- expect(q.message_count).to eq 1
50
-
51
- _, _, payload = q.pop
52
- expect(payload.bytesize).to eq as.bytesize
53
-
54
- ch.close
55
- end
56
- end
57
-
58
-
59
-
60
- context "with empty message body" do
61
- it "successfully publishes the message" do
62
- ch = @connection.create_channel
63
-
64
- q = ch.queue("", exclusive: true)
65
- x = ch.default_exchange
66
-
67
- x.publish("", routing_key: q.name, persistent: true)
68
-
69
- sleep(1)
70
- expect(q.message_count).to eq 1
71
-
72
- envelope, headers, payload = q.pop
73
-
74
- expect(payload).to eq ""
75
-
76
- expect(headers[:content_type]).to eq "application/octet-stream"
77
- expect(headers[:delivery_mode]).to eq 2
78
- expect(headers[:priority]).to eq 0
79
-
80
- ch.close
81
- end
82
- end
83
-
84
-
85
- context "with payload being 2 bytes less than 128K bytes in size" do
86
- it "successfully frames the message" do
87
- ch = @connection.create_channel
88
-
89
- q = ch.queue("", exclusive: true)
90
- x = ch.default_exchange
91
-
92
- as = "a" * (1024 * 128 - 2)
93
- x.publish(as, routing_key: q.name, persistent: true)
94
-
95
- sleep(1)
96
- expect(q.message_count).to eq 1
97
-
98
- q.purge
99
- ch.close
100
- end
101
- end
102
-
103
- context "with payload being 1 byte less than 128K bytes in size" do
104
- it "successfully frames the message" do
105
- ch = @connection.create_channel
106
-
107
- q = ch.queue("", exclusive: true)
108
- x = ch.default_exchange
109
-
110
- as = "a" * (1024 * 128 - 1)
111
- x.publish(as, routing_key: q.name, persistent: true)
112
-
113
- sleep(1)
114
- expect(q.message_count).to eq 1
115
-
116
- q.purge
117
- ch.close
118
- end
119
- end
120
-
121
- context "with payload being exactly 128K bytes in size" do
122
- it "successfully frames the message" do
123
- ch = @connection.create_channel
124
-
125
- q = ch.queue("", exclusive: true)
126
- x = ch.default_exchange
127
-
128
- as = "a" * (1024 * 128)
129
- x.publish(as, routing_key: q.name, persistent: true)
130
-
131
- sleep(1)
132
- expect(q.message_count).to eq 1
133
-
134
- q.purge
135
- ch.close
136
- end
137
- end
138
-
139
-
140
- context "with payload being 1 byte greater than 128K bytes in size" do
141
- it "successfully frames the message" do
142
- ch = @connection.create_channel
143
-
144
- q = ch.queue("", exclusive: true)
145
- x = ch.default_exchange
146
-
147
- as = "a" * (1024 * 128 + 1)
148
- x.publish(as, routing_key: q.name, persistent: true)
149
-
150
- sleep(1)
151
- expect(q.message_count).to eq 1
152
-
153
- q.purge
154
- ch.close
155
- end
156
- end
157
-
158
- context "with payload being 2 bytes greater than 128K bytes in size" do
159
- it "successfully frames the message" do
160
- ch = @connection.create_channel
161
-
162
- q = ch.queue("", exclusive: true)
163
- x = ch.default_exchange
164
-
165
- as = "a" * (1024 * 128 + 2)
166
- x.publish(as, routing_key: q.name, persistent: true)
167
-
168
- sleep(1)
169
- expect(q.message_count).to eq 1
170
-
171
- q.purge
172
- ch.close
173
- end
174
- end
175
- end
@@ -1,83 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Bunny::Channel, "#basic_cancel" do
4
- before(:all) do
5
- @connection = Bunny.new(:user => "bunny_gem", password: "bunny_password", :vhost => "bunny_testbed")
6
- @connection.start
7
- end
8
-
9
- after :all do
10
- @connection.close if @connection.open?
11
- end
12
-
13
- let(:queue_name) { "bunny.queues.#{rand}" }
14
-
15
- it "returns basic.cancel-ok" do
16
- ch = @connection.create_channel
17
- q = ch.queue("", :exclusive => true)
18
-
19
- consume_ok = ch.basic_consume(q, "")
20
- cancel_ok = ch.basic_cancel(consume_ok.consumer_tag)
21
-
22
- expect(cancel_ok).to be_instance_of AMQ::Protocol::Basic::CancelOk
23
- expect(cancel_ok.consumer_tag).to eq consume_ok.consumer_tag
24
-
25
- ch.close
26
- end
27
-
28
- context "when the given consumer tag is valid" do
29
- let(:queue_name) { "bunny.basic.cancel.queue#{rand}" }
30
-
31
- it "cancels the consumer" do
32
- delivered_data = []
33
-
34
- t = Thread.new do
35
- ch = @connection.create_channel
36
- q = ch.queue(queue_name, :auto_delete => true, :durable => false)
37
- consume_ok = ch.basic_consume(q, "", true, false) do |_, _, payload|
38
- delivered_data << payload
39
- end
40
-
41
- expect(consume_ok.consumer_tag).not_to be_nil
42
- cancel_ok = ch.basic_cancel(consume_ok.consumer_tag)
43
- expect(cancel_ok.consumer_tag).to eq consume_ok.consumer_tag
44
-
45
- ch.close
46
- end
47
- t.abort_on_exception = true
48
- sleep 0.5
49
-
50
- ch = @connection.create_channel
51
- ch.default_exchange.publish("", :routing_key => queue_name)
52
-
53
- sleep 0.7
54
- expect(delivered_data).to be_empty
55
- end
56
- end
57
-
58
- context "when the given consumer tag is invalid (was never registered)" do
59
- it "DOES NOT cause a channel error" do
60
- ch = @connection.create_channel
61
-
62
- # RabbitMQ 3.1 does not raise an exception w/ unknown consumer tag. MK.
63
- ch.basic_cancel("878798s7df89#{rand}#{Time.now.to_i}")
64
-
65
- ch.close
66
- end
67
- end
68
-
69
- context "when the given consumer tag belongs to a different channel" do
70
- it "DOES NOT cause a channel error" do
71
- ch1 = @connection.create_channel
72
- ch2 = @connection.create_channel
73
-
74
- q = ch1.queue("", :exclusive => true)
75
- cons = q.subscribe do |_, _, _|
76
- end
77
- ch2.basic_cancel(cons.consumer_tag)
78
-
79
- ch1.close
80
- ch2.close
81
- end
82
- end
83
- end
@@ -1,99 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Bunny::Channel, "#basic_consume" do
4
- before(:all) do
5
- @connection = Bunny.new(:user => "bunny_gem", password: "bunny_password", :vhost => "bunny_testbed")
6
- @connection.start
7
- end
8
-
9
- after :all do
10
- @connection.close if @connection.open?
11
- end
12
-
13
- it "returns basic.consume-ok when it is received" do
14
- ch = @connection.create_channel
15
- q = ch.queue("", exclusive: true)
16
-
17
- consume_ok = ch.basic_consume(q)
18
- expect(consume_ok).to be_instance_of AMQ::Protocol::Basic::ConsumeOk
19
- expect(consume_ok.consumer_tag).not_to be_nil
20
-
21
- ch.close
22
- end
23
-
24
- it "carries server-generated consumer tag with basic.consume-ok" do
25
- ch = @connection.create_channel
26
- q = ch.queue("", exclusive: true)
27
-
28
- consume_ok = ch.basic_consume(q, "")
29
- expect(consume_ok.consumer_tag).to match /amq\.ctag.*/
30
-
31
- ch.close
32
- end
33
-
34
- context "with automatic acknowledgement mode" do
35
- let(:queue_name) { "bunny.basic_consume#{rand}" }
36
-
37
- it "causes messages to be automatically removed from the queue after delivery" do
38
- delivered_keys = []
39
- delivered_data = []
40
-
41
- t = Thread.new do
42
- ch = @connection.create_channel
43
- q = ch.queue(queue_name, :auto_delete => true, :durable => false)
44
- ch.basic_consume(q, "", true, false) do |delivery_info, properties, payload|
45
- delivered_keys << delivery_info.routing_key
46
- delivered_data << payload
47
- end
48
- end
49
- t.abort_on_exception = true
50
- sleep 0.5
51
-
52
- ch = @connection.create_channel
53
- x = ch.default_exchange
54
- x.publish("hello", routing_key: queue_name)
55
-
56
- sleep 0.7
57
- expect(delivered_keys).to include queue_name
58
- expect(delivered_data).to include "hello"
59
-
60
- expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
61
-
62
- ch.close
63
- end
64
- end
65
-
66
- context "with manual acknowledgement mode" do
67
- let(:queue_name) { "bunny.basic_consume#{rand}" }
68
-
69
- it "waits for an explicit acknowledgement" do
70
- delivered_keys = []
71
- delivered_data = []
72
-
73
- t = Thread.new do
74
- ch = @connection.create_channel
75
- q = ch.queue(queue_name, auto_delete: true, durable: false)
76
- ch.basic_consume(q, "", false, false) do |delivery_info, properties, payload|
77
- delivered_keys << delivery_info.routing_key
78
- delivered_data << payload
79
-
80
- ch.close
81
- end
82
- end
83
- t.abort_on_exception = true
84
- sleep 0.5
85
-
86
- ch = @connection.create_channel
87
- x = ch.default_exchange
88
- x.publish("hello", routing_key: queue_name)
89
-
90
- sleep 0.7
91
- expect(delivered_keys).to include queue_name
92
- expect(delivered_data).to include "hello"
93
-
94
- expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
95
-
96
- ch.close
97
- end
98
- end
99
- end
data/spec/spec_helper.rb DELETED
@@ -1,47 +0,0 @@
1
- # -*- encoding: utf-8; mode: ruby -*-
2
-
3
- $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
4
-
5
- require 'bundler'
6
- Bundler.require(:default, :test)
7
-
8
- require "bunny"
9
- require "bunny/test_kit"
10
-
11
- puts "Using Ruby #{RUBY_VERSION}, amq-protocol #{AMQ::Protocol::VERSION}"
12
-
13
- module RabbitMQ
14
- module Control
15
-
16
- RABBITMQ_NODENAME = ENV['RABBITMQ_NODENAME'] || 'rabbit'
17
-
18
- def rabbitmq_pid
19
- $1.to_i if `rabbitmqctl -n #{RABBITMQ_NODENAME} status` =~ /\{pid,(\d+)\}/
20
- end
21
-
22
- def start_rabbitmq(delay = 1.0)
23
- # this is Homebrew-specific :(
24
- `RABBITMQ_NODENAME=#{RABBITMQ_NODENAME} rabbitmq-server > /dev/null 2>&1 &`; sleep(delay)
25
- end
26
-
27
- def stop_rabbitmq(pid = rabbitmq_pid, delay = 1.0)
28
- `rabbitmqctl -n #{RABBITMQ_NODENAME} stop`; sleep(delay)
29
- end
30
-
31
- def kill_rabbitmq(pid = rabbitmq_pid, delay = 1.0)
32
- # tango is down, tango is down!
33
- Process.kill("KILL", pid); sleep(delay)
34
- end
35
- end
36
- end
37
-
38
-
39
- module PlatformDetection
40
- def mri?
41
- !defined?(RUBY_ENGINE) || (defined?(RUBY_ENGINE) && ("ruby" == RUBY_ENGINE))
42
- end
43
-
44
- def rubinius?
45
- defined?(RUBY_ENGINE) && (RUBY_ENGINE == 'rbx')
46
- end
47
- end
@@ -1,64 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "Rapidly closing lots of temporary channels" do
4
- before :all do
5
- @connection = Bunny.new(automatic_recovery: false).tap do |c|
6
- c.start
7
- end
8
- end
9
-
10
- after :all do
11
- @connection.close
12
- end
13
-
14
- 100.times do |i|
15
- context "in a multi-threaded scenario A (take #{i})" do
16
- let(:n) { 20 }
17
-
18
- it "works correctly" do
19
- ts = []
20
-
21
- n.times do
22
- t = Thread.new do
23
- @connection.with_channel do |ch1|
24
- q = ch1.queue("", exclusive: true)
25
- q.delete
26
- ch1.close
27
- end
28
-
29
- ch2 = @connection.create_channel
30
- ch2.close
31
- end
32
- t.abort_on_exception = true
33
- ts << t
34
- end
35
-
36
- ts.each { |t| t.join }
37
- end
38
- end
39
- end
40
-
41
- 100.times do |i|
42
- context "in a multi-threaded scenario B (take #{i})" do
43
- let(:n) { 20 }
44
-
45
- it "works correctly" do
46
- ts = []
47
-
48
- n.times do
49
- t = Thread.new do
50
- 3.times do
51
- @connection.with_channel do |ch|
52
- x = ch.topic('bunny.stress.topics.t2', durable: false)
53
- end
54
- end
55
- end
56
- t.abort_on_exception = true
57
- ts << t
58
- end
59
-
60
- ts.each { |t| t.join }
61
- end
62
- end
63
- end
64
- end
@@ -1,84 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "Rapidly opening and closing lots of channels" do
4
- before :all do
5
- @connection = Bunny.new(automatic_recovery: false).tap do |c|
6
- c.start
7
- end
8
- end
9
-
10
- after :all do
11
- @connection.close
12
- end
13
-
14
- context "in a single-threaded scenario" do
15
- let(:n) { 500 }
16
-
17
- it "works correctly" do
18
- xs = Array.new(n) { @connection.create_channel }
19
- puts "Opened #{n} channels"
20
-
21
- expect(xs.size).to eq n
22
- xs.each do |ch|
23
- ch.close
24
- end
25
- end
26
- end
27
-
28
- 100.times do |i|
29
- context "in a multi-threaded scenario A (take #{i})" do
30
- # actually, on MRI values greater than ~100 will eventually cause write
31
- # operations to fail with a timeout (1 second is not enough)
32
- # which will cause recovery to re-acquire @channel_mutex in Session.
33
- # Because Ruby's mutexes are not re-entrant, it will raise a ThreadError.
34
- #
35
- # But this already demonstrates that within these platform constraints,
36
- # Bunny is safe to use in such scenarios.
37
- let(:n) { 20 }
38
-
39
- it "works correctly" do
40
- ts = []
41
-
42
- n.times do
43
- t = Thread.new do
44
- ch1 = @connection.create_channel
45
- q = ch1.queue("", exclusive: true)
46
- q.delete
47
- ch1.close
48
-
49
- ch2 = @connection.create_channel
50
- ch2.close
51
- end
52
- t.abort_on_exception = true
53
- ts << t
54
- end
55
-
56
- ts.each { |t| t.join }
57
- end
58
- end
59
- end
60
-
61
- 100.times do |i|
62
- context "in a multi-threaded scenario B (take #{i})" do
63
- let(:n) { 20 }
64
-
65
- it "works correctly" do
66
- ts = []
67
-
68
- n.times do
69
- t = Thread.new do
70
- 3.times do
71
- ch = @connection.create_channel
72
- x = ch.topic('bunny.stress.topics.t2', durable: false)
73
- ch.close
74
- end
75
- end
76
- t.abort_on_exception = true
77
- ts << t
78
- end
79
-
80
- ts.each { |t| t.join }
81
- end
82
- end
83
- end
84
- end
@@ -1,28 +0,0 @@
1
- require "spec_helper"
2
-
3
- unless ENV["CI"]
4
- describe "Rapidly opening and closing lots of channels on a non-threaded connection" do
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
- end
10
-
11
- after :all do
12
- @connection.close
13
- end
14
-
15
- context "in a single-threaded scenario" do
16
- let(:n) { 500 }
17
-
18
- it "works correctly" do
19
- xs = Array.new(n) { @connection.create_channel }
20
-
21
- expect(xs.size).to eq n
22
- xs.each do |ch|
23
- ch.close
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,71 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require "spec_helper"
3
-
4
- unless ENV["CI"]
5
- describe "Concurrent consumers sharing a connection" do
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
10
- end
11
-
12
- after :all do
13
- @connection.close
14
- end
15
-
16
- def any_not_drained?(qs)
17
- qs.any? { |q| !q.message_count.zero? }
18
- end
19
-
20
- context "when publishing thousands of messages over 128K in size" do
21
- let(:colors) { ["red", "blue", "white"] }
22
-
23
- let(:n) { 16 }
24
- let(:m) { 5000 }
25
-
26
- it "successfully drain all queues" do
27
- ch0 = @connection.create_channel
28
- ch0.confirm_select
29
- body = "абвг"
30
- x = ch0.topic("bunny.stress.concurrent.consumers.topic", durable: true)
31
-
32
- chs = {}
33
- n.times do |i|
34
- chs[i] = @connection.create_channel
35
- end
36
- qs = []
37
-
38
- n.times do |i|
39
- t = Thread.new do
40
- cht = chs[i]
41
-
42
- q = cht.queue("", exclusive: true)
43
- q.bind(x.name, routing_key: colors.sample).subscribe do |delivery_info, meta, payload|
44
- # no-op
45
- end
46
- qs << q
47
- end
48
- t.abort_on_exception = true
49
- end
50
-
51
- sleep 1.0
52
-
53
- 5.times do |i|
54
- m.times do
55
- x.publish(body, routing_key: colors.sample)
56
- end
57
- puts "Published #{(i + 1) * m} messages..."
58
- ch0.wait_for_confirms
59
- end
60
-
61
- while any_not_drained?(qs)
62
- sleep 1.0
63
- end
64
- puts "Drained all queues, winding down..."
65
-
66
- ch0.close
67
- chs.each { |_, ch| ch.close }
68
- end
69
- end
70
- end
71
- end
@@ -1,54 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require "spec_helper"
3
-
4
- unless ENV["CI"]
5
- describe "Concurrent publishers sharing a connection" do
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
- end
11
-
12
- after :all do
13
- @connection.close
14
- end
15
-
16
- let(:concurrency) { 24 }
17
- let(:messages) { 5_000 }
18
-
19
- it "successfully finish publishing" do
20
- body = "сообщение"
21
-
22
- chs = {}
23
- concurrency.times do |i|
24
- ch = @connection.create_channel
25
- ch.confirm_select
26
- chs[i] = ch
27
- end
28
-
29
- ts = []
30
-
31
- concurrency.times do |i|
32
- t = Thread.new do
33
- cht = chs[i]
34
- x = cht.default_exchange
35
-
36
- messages.times do
37
- x.publish(body)
38
- end
39
- puts "Published #{messages} messages..."
40
- cht.wait_for_confirms
41
- end
42
- t.abort_on_exception = true
43
-
44
- ts << t
45
- end
46
-
47
- ts.each do |t|
48
- t.join
49
- end
50
-
51
- chs.each { |_, ch| ch.close }
52
- end
53
- end
54
- end