bunny 2.7.4 → 2.22.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 (156) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +61 -35
  3. data/lib/bunny/channel.rb +186 -50
  4. data/lib/bunny/channel_id_allocator.rb +3 -1
  5. data/lib/bunny/consumer.rb +2 -2
  6. data/lib/bunny/consumer_work_pool.rb +2 -1
  7. data/lib/bunny/cruby/socket.rb +3 -0
  8. data/lib/bunny/cruby/ssl_socket.rb +6 -1
  9. data/lib/bunny/delivery_info.rb +1 -1
  10. data/lib/bunny/heartbeat_sender.rb +2 -1
  11. data/lib/bunny/jruby/ssl_socket.rb +5 -0
  12. data/lib/bunny/queue.rb +36 -8
  13. data/lib/bunny/reader_loop.rb +22 -10
  14. data/lib/bunny/session.rb +152 -65
  15. data/lib/bunny/test_kit.rb +14 -0
  16. data/lib/bunny/transport.rb +132 -49
  17. data/lib/bunny/version.rb +1 -1
  18. data/lib/bunny.rb +45 -4
  19. metadata +37 -225
  20. data/.github/ISSUE_TEMPLATE.md +0 -18
  21. data/.gitignore +0 -28
  22. data/.rspec +0 -1
  23. data/.travis.yml +0 -20
  24. data/.yardopts +0 -8
  25. data/CONTRIBUTING.md +0 -111
  26. data/ChangeLog.md +0 -1831
  27. data/Gemfile +0 -53
  28. data/LICENSE +0 -21
  29. data/Rakefile +0 -46
  30. data/benchmarks/basic_publish/with_128K_messages.rb +0 -35
  31. data/benchmarks/basic_publish/with_1k_messages.rb +0 -35
  32. data/benchmarks/basic_publish/with_4K_messages.rb +0 -35
  33. data/benchmarks/basic_publish/with_64K_messages.rb +0 -35
  34. data/benchmarks/channel_open.rb +0 -28
  35. data/benchmarks/mutex_and_monitor.rb +0 -42
  36. data/benchmarks/queue_declare.rb +0 -29
  37. data/benchmarks/queue_declare_and_bind.rb +0 -29
  38. data/benchmarks/queue_declare_bind_and_delete.rb +0 -29
  39. data/benchmarks/synchronized_sorted_set.rb +0 -53
  40. data/benchmarks/write_vs_write_nonblock.rb +0 -49
  41. data/bin/ci/before_build +0 -46
  42. data/bunny.gemspec +0 -35
  43. data/docker/Dockerfile +0 -16
  44. data/docker/docker-entrypoint.sh +0 -37
  45. data/docker-compose.yml +0 -18
  46. data/examples/connection/authentication_failure.rb +0 -16
  47. data/examples/connection/automatic_recovery_with_basic_get.rb +0 -40
  48. data/examples/connection/automatic_recovery_with_client_named_queues.rb +0 -36
  49. data/examples/connection/automatic_recovery_with_multiple_consumers.rb +0 -46
  50. data/examples/connection/automatic_recovery_with_republishing.rb +0 -109
  51. data/examples/connection/automatic_recovery_with_server_named_queues.rb +0 -35
  52. data/examples/connection/channel_level_exception.rb +0 -27
  53. data/examples/connection/disabled_automatic_recovery.rb +0 -34
  54. data/examples/connection/heartbeat.rb +0 -17
  55. data/examples/connection/manually_reconnecting_consumer.rb +0 -23
  56. data/examples/connection/manually_reconnecting_publisher.rb +0 -28
  57. data/examples/connection/unknown_host.rb +0 -16
  58. data/examples/consumers/high_and_low_priority.rb +0 -50
  59. data/examples/guides/exchanges/direct_exchange_routing.rb +0 -36
  60. data/examples/guides/exchanges/fanout_exchange_routing.rb +0 -28
  61. data/examples/guides/exchanges/headers_exchange_routing.rb +0 -31
  62. data/examples/guides/exchanges/mandatory_messages.rb +0 -30
  63. data/examples/guides/extensions/alternate_exchange.rb +0 -30
  64. data/examples/guides/extensions/basic_nack.rb +0 -33
  65. data/examples/guides/extensions/connection_blocked.rb +0 -35
  66. data/examples/guides/extensions/consumer_cancellation_notification.rb +0 -39
  67. data/examples/guides/extensions/dead_letter_exchange.rb +0 -32
  68. data/examples/guides/extensions/exchange_to_exchange_bindings.rb +0 -29
  69. data/examples/guides/extensions/per_message_ttl.rb +0 -36
  70. data/examples/guides/extensions/per_queue_message_ttl.rb +0 -36
  71. data/examples/guides/extensions/publisher_confirms.rb +0 -28
  72. data/examples/guides/extensions/queue_lease.rb +0 -26
  73. data/examples/guides/extensions/sender_selected_distribution.rb +0 -32
  74. data/examples/guides/getting_started/blabbr.rb +0 -27
  75. data/examples/guides/getting_started/hello_world.rb +0 -22
  76. data/examples/guides/getting_started/weathr.rb +0 -49
  77. data/examples/guides/queues/one_off_consumer.rb +0 -25
  78. data/examples/guides/queues/redeliveries.rb +0 -81
  79. data/profiling/basic_publish/with_4K_messages.rb +0 -33
  80. data/repl +0 -3
  81. data/spec/config/enabled_plugins +0 -1
  82. data/spec/config/rabbitmq.config +0 -19
  83. data/spec/higher_level_api/integration/basic_ack_spec.rb +0 -230
  84. data/spec/higher_level_api/integration/basic_cancel_spec.rb +0 -142
  85. data/spec/higher_level_api/integration/basic_consume_spec.rb +0 -349
  86. data/spec/higher_level_api/integration/basic_consume_with_objects_spec.rb +0 -54
  87. data/spec/higher_level_api/integration/basic_get_spec.rb +0 -80
  88. data/spec/higher_level_api/integration/basic_nack_spec.rb +0 -82
  89. data/spec/higher_level_api/integration/basic_publish_spec.rb +0 -74
  90. data/spec/higher_level_api/integration/basic_qos_spec.rb +0 -57
  91. data/spec/higher_level_api/integration/basic_reject_spec.rb +0 -152
  92. data/spec/higher_level_api/integration/basic_return_spec.rb +0 -33
  93. data/spec/higher_level_api/integration/channel_close_spec.rb +0 -25
  94. data/spec/higher_level_api/integration/channel_open_spec.rb +0 -57
  95. data/spec/higher_level_api/integration/connection_recovery_spec.rb +0 -471
  96. data/spec/higher_level_api/integration/connection_spec.rb +0 -559
  97. data/spec/higher_level_api/integration/connection_stop_spec.rb +0 -83
  98. data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +0 -128
  99. data/spec/higher_level_api/integration/dead_lettering_spec.rb +0 -75
  100. data/spec/higher_level_api/integration/exchange_bind_spec.rb +0 -31
  101. data/spec/higher_level_api/integration/exchange_declare_spec.rb +0 -237
  102. data/spec/higher_level_api/integration/exchange_delete_spec.rb +0 -105
  103. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +0 -40
  104. data/spec/higher_level_api/integration/exclusive_queue_spec.rb +0 -28
  105. data/spec/higher_level_api/integration/heartbeat_spec.rb +0 -49
  106. data/spec/higher_level_api/integration/merry_go_round_spec.rb +0 -85
  107. data/spec/higher_level_api/integration/message_properties_access_spec.rb +0 -95
  108. data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +0 -24
  109. data/spec/higher_level_api/integration/publisher_confirms_spec.rb +0 -191
  110. data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +0 -87
  111. data/spec/higher_level_api/integration/queue_bind_spec.rb +0 -109
  112. data/spec/higher_level_api/integration/queue_declare_spec.rb +0 -221
  113. data/spec/higher_level_api/integration/queue_delete_spec.rb +0 -41
  114. data/spec/higher_level_api/integration/queue_purge_spec.rb +0 -30
  115. data/spec/higher_level_api/integration/queue_unbind_spec.rb +0 -54
  116. data/spec/higher_level_api/integration/read_only_consumer_spec.rb +0 -60
  117. data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +0 -36
  118. data/spec/higher_level_api/integration/tls_connection_spec.rb +0 -222
  119. data/spec/higher_level_api/integration/tx_commit_spec.rb +0 -21
  120. data/spec/higher_level_api/integration/tx_rollback_spec.rb +0 -21
  121. data/spec/higher_level_api/integration/with_channel_spec.rb +0 -25
  122. data/spec/issues/issue100_spec.rb +0 -42
  123. data/spec/issues/issue141_spec.rb +0 -43
  124. data/spec/issues/issue202_spec.rb +0 -15
  125. data/spec/issues/issue224_spec.rb +0 -40
  126. data/spec/issues/issue465_spec.rb +0 -32
  127. data/spec/issues/issue78_spec.rb +0 -72
  128. data/spec/issues/issue83_spec.rb +0 -30
  129. data/spec/issues/issue97_attachment.json +0 -1
  130. data/spec/issues/issue97_spec.rb +0 -175
  131. data/spec/lower_level_api/integration/basic_cancel_spec.rb +0 -83
  132. data/spec/lower_level_api/integration/basic_consume_spec.rb +0 -99
  133. data/spec/spec_helper.rb +0 -51
  134. data/spec/stress/channel_close_stress_spec.rb +0 -64
  135. data/spec/stress/channel_open_stress_spec.rb +0 -84
  136. data/spec/stress/channel_open_stress_with_single_threaded_connection_spec.rb +0 -28
  137. data/spec/stress/concurrent_consumers_stress_spec.rb +0 -71
  138. data/spec/stress/concurrent_publishers_stress_spec.rb +0 -54
  139. data/spec/stress/connection_open_close_spec.rb +0 -52
  140. data/spec/stress/long_running_consumer_spec.rb +0 -84
  141. data/spec/tls/ca_certificate.pem +0 -29
  142. data/spec/tls/ca_key.pem +0 -52
  143. data/spec/tls/client_certificate.pem +0 -29
  144. data/spec/tls/client_key.pem +0 -51
  145. data/spec/tls/generate-server-cert.sh +0 -8
  146. data/spec/tls/server-openssl.cnf +0 -10
  147. data/spec/tls/server.csr +0 -16
  148. data/spec/tls/server_certificate.pem +0 -29
  149. data/spec/tls/server_key.pem +0 -51
  150. data/spec/unit/bunny_spec.rb +0 -15
  151. data/spec/unit/concurrent/atomic_fixnum_spec.rb +0 -35
  152. data/spec/unit/concurrent/condition_spec.rb +0 -82
  153. data/spec/unit/concurrent/linked_continuation_queue_spec.rb +0 -35
  154. data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +0 -73
  155. data/spec/unit/exchange_recovery_spec.rb +0 -39
  156. 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,51 +0,0 @@
1
- # -*- encoding: utf-8; mode: ruby -*-
2
-
3
- $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
4
-
5
- require 'bundler'
6
- Bundler.setup(:default, :test)
7
-
8
-
9
- require "effin_utf8"
10
- require "bunny"
11
- require "rabbitmq/http/client"
12
-
13
-
14
- require "amq/protocol/version"
15
- puts "Using Ruby #{RUBY_VERSION}, amq-protocol #{AMQ::Protocol::VERSION}"
16
-
17
- module RabbitMQ
18
- module Control
19
-
20
- RABBITMQ_NODENAME = ENV['RABBITMQ_NODENAME'] || 'rabbit'
21
-
22
- def rabbitmq_pid
23
- $1.to_i if `rabbitmqctl -n #{RABBITMQ_NODENAME} status` =~ /\{pid,(\d+)\}/
24
- end
25
-
26
- def start_rabbitmq(delay = 1.0)
27
- # this is Homebrew-specific :(
28
- `RABBITMQ_NODENAME=#{RABBITMQ_NODENAME} rabbitmq-server > /dev/null 2>&1 &`; sleep(delay)
29
- end
30
-
31
- def stop_rabbitmq(pid = rabbitmq_pid, delay = 1.0)
32
- `rabbitmqctl -n #{RABBITMQ_NODENAME} stop`; sleep(delay)
33
- end
34
-
35
- def kill_rabbitmq(pid = rabbitmq_pid, delay = 1.0)
36
- # tango is down, tango is down!
37
- Process.kill("KILL", pid); sleep(delay)
38
- end
39
- end
40
- end
41
-
42
-
43
- module PlatformDetection
44
- def mri?
45
- !defined?(RUBY_ENGINE) || (defined?(RUBY_ENGINE) && ("ruby" == RUBY_ENGINE))
46
- end
47
-
48
- def rubinius?
49
- defined?(RUBY_ENGINE) && (RUBY_ENGINE == 'rbx')
50
- end
51
- 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