bunny 2.7.4 → 2.22.0

Sign up to get free protection for your applications and to get access to all the features.
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,230 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Bunny::Channel, "#ack" do
4
- let(:connection) do
5
- c = Bunny.new(username: "bunny_gem", password: "bunny_password", vhost: "bunny_testbed")
6
- c.start
7
- c
8
- end
9
-
10
- after :each do
11
- connection.close if connection.open?
12
- end
13
-
14
- context "with a valid (known) delivery tag" do
15
- it "acknowledges a message" do
16
- ch = connection.create_channel
17
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
18
- x = ch.default_exchange
19
-
20
- x.publish("bunneth", routing_key: q.name)
21
- sleep 0.5
22
- expect(q.message_count).to eq 1
23
- delivery_details, properties, content = q.pop(manual_ack: true)
24
-
25
- ch.ack(delivery_details.delivery_tag, true)
26
- ch.close
27
-
28
- ch = connection.create_channel
29
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
30
- expect(q.message_count).to eq 0
31
- ch.close
32
- end
33
- end
34
-
35
- context "with a valid (known) delivery tag (multiple = true)" do
36
- it "acknowledges a message" do
37
- ch = connection.create_channel
38
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
39
- x = ch.default_exchange
40
-
41
- x.publish("bunneth", routing_key: q.name)
42
- x.publish("bunneth", routing_key: q.name)
43
- sleep 0.5
44
- expect(q.message_count).to eq 2
45
- delivery_details_1, _properties, _content = q.pop(manual_ack: true)
46
- delivery_details_2, _properties, _content = q.pop(manual_ack: true)
47
-
48
- ch.ack(delivery_details_2.delivery_tag, true)
49
- ch.close
50
-
51
- ch = connection.create_channel
52
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
53
- expect(q.message_count).to eq 0
54
- ch.close
55
- end
56
- end
57
-
58
- context "with a valid (known) delivery tag (multiple = false)" do
59
- it "acknowledges a message" do
60
- ch = connection.create_channel
61
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
62
- x = ch.default_exchange
63
-
64
- x.publish("bunneth", routing_key: q.name)
65
- x.publish("bunneth", routing_key: q.name)
66
- sleep 0.5
67
- expect(q.message_count).to eq 2
68
- delivery_details_1, _properties, _content = q.pop(manual_ack: true)
69
- delivery_details_2, _properties, _content = q.pop(manual_ack: true)
70
-
71
- ch.ack(delivery_details_2.delivery_tag, false)
72
- ch.close
73
-
74
- ch = connection.create_channel
75
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
76
- expect(q.message_count).to eq 1
77
- ch.close
78
- end
79
- end
80
-
81
- context "with a valid (known) delivery tag and automatic ack mode" do
82
- it "results in a channel exception" do
83
- ch = connection.create_channel
84
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
85
- x = ch.default_exchange
86
-
87
- q.subscribe(manual_ack: false) do |delivery_info, properties, payload|
88
- ch.ack(delivery_info.delivery_tag, false)
89
- end
90
-
91
- x.publish("bunneth", routing_key: q.name)
92
- sleep 0.5
93
- expect do
94
- q.message_count
95
- end.to raise_error(Bunny::ChannelAlreadyClosed)
96
- end
97
- end
98
-
99
- context "with an invalid (random) delivery tag" do
100
- it "causes a channel-level error" do
101
- ch = connection.create_channel
102
- q = ch.queue("bunny.basic.ack.unknown-delivery-tag", exclusive: true)
103
- x = ch.default_exchange
104
-
105
- x.publish("bunneth", routing_key: q.name)
106
- sleep 0.5
107
- expect(q.message_count).to eq 1
108
- _, _, content = q.pop(manual_ack: true)
109
-
110
- ch.on_error do |ch, channel_close|
111
- @channel_close = channel_close
112
- end
113
- ch.ack(82, true)
114
- sleep 0.25
115
-
116
- expect(@channel_close.reply_code).to eq AMQ::Protocol::PreconditionFailed::VALUE
117
- end
118
- end
119
-
120
- context "with a valid (known) delivery tag" do
121
- it "gets a depricated message warning for using :ack" do
122
- ch = connection.create_channel
123
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
124
- x = ch.default_exchange
125
-
126
- x.publish("bunneth", routing_key: q.name)
127
- sleep 0.5
128
- expect(q.message_count).to eq 1
129
-
130
- orig_stderr = $stderr
131
- $stderr = StringIO.new
132
-
133
- delivery_details, properties, content = q.pop(ack: true)
134
-
135
- $stderr.rewind
136
- expect($stderr.string.chomp).to eq("[DEPRECATION] `:ack` is deprecated. Please use `:manual_ack` instead.\n[DEPRECATION] `:ack` is deprecated. Please use `:manual_ack` instead.")
137
-
138
- $stderr = orig_stderr
139
-
140
- ch.ack(delivery_details.delivery_tag, true)
141
- ch.close
142
-
143
- ch = connection.create_channel
144
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
145
- expect(q.message_count).to eq 0
146
- ch.close
147
- end
148
- end
149
- end
150
-
151
- describe Bunny::Channel, "#basic_ack" do
152
- let(:connection) do
153
- c = Bunny.new(username: "bunny_gem", password: "bunny_password", vhost: "bunny_testbed")
154
- c.start
155
- c
156
- end
157
-
158
- after :each do
159
- connection.close if connection.open?
160
- end
161
-
162
- context "with a valid (known) delivery tag (multiple = true)" do
163
- it "acknowledges a message" do
164
- ch = connection.create_channel
165
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
166
- x = ch.default_exchange
167
-
168
- x.publish("bunneth", routing_key: q.name)
169
- x.publish("bunneth", routing_key: q.name)
170
- sleep 0.5
171
- expect(q.message_count).to eq 2
172
- delivery_details_1, _properties, _content = q.pop(manual_ack: true)
173
- delivery_details_2, _properties, _content = q.pop(manual_ack: true)
174
-
175
- ch.basic_ack(delivery_details_2.delivery_tag.to_i, true)
176
- ch.close
177
-
178
- ch = connection.create_channel
179
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
180
- expect(q.message_count).to eq 0
181
- ch.close
182
- end
183
- end
184
-
185
- context "with a valid (known) delivery tag (multiple = false)" do
186
- it "acknowledges a message" do
187
- ch = connection.create_channel
188
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
189
- x = ch.default_exchange
190
-
191
- x.publish("bunneth", routing_key: q.name)
192
- x.publish("bunneth", routing_key: q.name)
193
- sleep 0.5
194
- expect(q.message_count).to eq 2
195
- delivery_details_1, _properties, _content = q.pop(manual_ack: true)
196
- delivery_details_2, _properties, _content = q.pop(manual_ack: true)
197
-
198
- ch.basic_ack(delivery_details_2.delivery_tag.to_i, false)
199
- ch.close
200
-
201
- ch = connection.create_channel
202
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
203
- expect(q.message_count).to eq 1
204
- ch.close
205
- end
206
- end
207
-
208
- context "with a valid (known) delivery tag (multiple = default)" do
209
- it "acknowledges a message" do
210
- ch = connection.create_channel
211
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
212
- x = ch.default_exchange
213
-
214
- x.publish("bunneth", routing_key: q.name)
215
- x.publish("bunneth", routing_key: q.name)
216
- sleep 0.5
217
- expect(q.message_count).to eq 2
218
- delivery_details_1, _properties, _content = q.pop(manual_ack: true)
219
- delivery_details_2, _properties, _content = q.pop(manual_ack: true)
220
-
221
- ch.basic_ack(delivery_details_2.delivery_tag.to_i)
222
- ch.close
223
-
224
- ch = connection.create_channel
225
- q = ch.queue("bunny.basic.ack.manual-acks", exclusive: true)
226
- expect(q.message_count).to eq 1
227
- ch.close
228
- end
229
- end
230
- end
@@ -1,142 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Bunny::Consumer, "#cancel" do
4
- let(:connection) do
5
- c = Bunny.new(username: "bunny_gem", password: "bunny_password", vhost: "bunny_testbed")
6
- c.start
7
- c
8
- end
9
-
10
- after :each do
11
- connection.close if connection.open?
12
- end
13
-
14
- context "with a non-blocking consumer" do
15
- let(:queue_name) { "bunny.queues.#{rand}" }
16
-
17
- it "cancels the consumer" do
18
- delivered_data = []
19
-
20
- t = Thread.new do
21
- ch = connection.create_channel
22
- q = ch.queue(queue_name, auto_delete: true, durable: false)
23
- consumer = q.subscribe(block: false) do |_, _, payload|
24
- delivered_data << payload
25
- end
26
-
27
- expect(consumer.consumer_tag).not_to be_nil
28
- cancel_ok = consumer.cancel
29
- expect(cancel_ok.consumer_tag).to eq consumer.consumer_tag
30
-
31
- ch.close
32
- end
33
- t.abort_on_exception = true
34
- sleep 0.5
35
-
36
- ch = connection.create_channel
37
- ch.default_exchange.publish("", routing_key: queue_name)
38
-
39
- sleep 0.7
40
- expect(delivered_data).to be_empty
41
- end
42
- end
43
-
44
-
45
- context "with a blocking consumer" do
46
- let(:queue_name) { "bunny.queues.#{rand}" }
47
-
48
- it "cancels the consumer" do
49
- delivered_data = []
50
- consumer = nil
51
-
52
- t = Thread.new do
53
- ch = connection.create_channel
54
- q = ch.queue(queue_name, auto_delete: true, durable: false)
55
-
56
- consumer = Bunny::Consumer.new(ch, q)
57
- consumer.on_delivery do |_, _, payload|
58
- delivered_data << payload
59
- end
60
-
61
- q.subscribe_with(consumer, block: false)
62
- end
63
- t.abort_on_exception = true
64
- sleep 1.0
65
-
66
- consumer.cancel
67
- sleep 1.0
68
-
69
- ch = connection.create_channel
70
- ch.default_exchange.publish("", routing_key: queue_name)
71
-
72
- sleep 0.7
73
- expect(delivered_data).to be_empty
74
- end
75
- end
76
-
77
- context "with a worker pool shutdown timeout configured" do
78
- let(:queue_name) { "bunny.queues.#{rand}" }
79
-
80
- it "processes the message if processing completes within the timeout" do
81
- delivered_data = []
82
- consumer = nil
83
-
84
- t = Thread.new do
85
- ch = connection.create_channel(nil, 1, false, 5)
86
- q = ch.queue(queue_name, auto_delete: true, durable: false)
87
-
88
- consumer = Bunny::Consumer.new(ch, q)
89
- consumer.on_delivery do |_, _, payload|
90
- sleep 2
91
- delivered_data << payload
92
- end
93
-
94
- q.subscribe_with(consumer, block: false)
95
- end
96
- t.abort_on_exception = true
97
- sleep 1.0
98
-
99
- ch = connection.create_channel
100
- ch.confirm_select
101
- ch.default_exchange.publish("", routing_key: queue_name)
102
- ch.wait_for_confirms
103
- sleep 0.5
104
-
105
- consumer.cancel
106
- sleep 1.0
107
-
108
- expect(delivered_data).to_not be_empty
109
- end
110
-
111
- it "kills the consumer if processing takes longer than the timeout" do
112
- delivered_data = []
113
- consumer = nil
114
-
115
- t = Thread.new do
116
- ch = connection.create_channel(nil, 1, false, 1)
117
- q = ch.queue(queue_name, auto_delete: true, durable: false)
118
-
119
- consumer = Bunny::Consumer.new(ch, q)
120
- consumer.on_delivery do |_, _, payload|
121
- sleep 3
122
- delivered_data << payload
123
- end
124
-
125
- q.subscribe_with(consumer, block: false)
126
- end
127
- t.abort_on_exception = true
128
- sleep 1.0
129
-
130
- ch = connection.create_channel
131
- ch.confirm_select
132
- ch.default_exchange.publish("", routing_key: queue_name)
133
- ch.wait_for_confirms
134
- sleep 0.5
135
-
136
- consumer.cancel
137
- sleep 1.0
138
-
139
- expect(delivered_data).to be_empty
140
- end
141
- end
142
- end
@@ -1,349 +0,0 @@
1
- require "spec_helper"
2
- require "set"
3
-
4
- describe Bunny::Queue, "#subscribe" do
5
- let(:connection) do
6
- c = Bunny.new(username: "bunny_gem", password: "bunny_password", vhost: "bunny_testbed")
7
- c.start
8
- c
9
- end
10
-
11
- after :each do
12
- connection.close if connection.open?
13
- end
14
-
15
- context "with automatic acknowledgement mode" do
16
- let(:queue_name) { "bunny.basic_consume#{rand}" }
17
-
18
- it "registers the consumer" do
19
- delivered_keys = []
20
- delivered_data = []
21
-
22
- t = Thread.new do
23
- ch = connection.create_channel
24
- q = ch.queue(queue_name, auto_delete: true, durable: false)
25
- q.subscribe(exclusive: false, manual_ack: false) do |delivery_info, properties, payload|
26
- delivered_keys << delivery_info.routing_key
27
- delivered_data << payload
28
- end
29
- end
30
- t.abort_on_exception = true
31
- sleep 0.5
32
-
33
- ch = connection.create_channel
34
- x = ch.default_exchange
35
- x.publish("hello", routing_key: queue_name)
36
-
37
- sleep 0.7
38
- expect(delivered_keys).to include(queue_name)
39
- expect(delivered_data).to include("hello")
40
-
41
- expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
42
-
43
- ch.close
44
- end
45
-
46
- context "with a single consumer" do
47
- let(:queue_name) { "bunny.basic_consume#{rand}" }
48
-
49
- it "provides delivery tag access" do
50
- delivery_tags = SortedSet.new
51
-
52
- cch = connection.create_channel
53
- q = cch.queue(queue_name, auto_delete: true, durable: false)
54
- q.subscribe(exclusive: false, manual_ack: false) do |delivery_info, properties, payload|
55
- delivery_tags << delivery_info.delivery_tag
56
- end
57
- sleep 0.5
58
-
59
- ch = connection.create_channel
60
- x = ch.default_exchange
61
- 100.times do
62
- x.publish("hello", routing_key: queue_name)
63
- end
64
-
65
- sleep 1.0
66
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
67
-
68
- expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
69
-
70
- ch.close
71
- end
72
- end
73
-
74
-
75
- context "with multiple consumers on the same channel" do
76
- let(:queue_name) { "bunny.basic_consume#{rand}" }
77
-
78
- it "provides delivery tag access" do
79
- delivery_tags = SortedSet.new
80
-
81
- cch = connection.create_channel
82
- q = cch.queue(queue_name, auto_delete: true, durable: false)
83
-
84
- 7.times do
85
- q.subscribe(exclusive: false, manual_ack: false) do |delivery_info, properties, payload|
86
- delivery_tags << delivery_info.delivery_tag
87
- end
88
- end
89
- sleep 1.0
90
-
91
- ch = connection.create_channel
92
- x = ch.default_exchange
93
- 100.times do
94
- x.publish("hello", routing_key: queue_name)
95
- end
96
-
97
- sleep 1.5
98
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
99
-
100
- expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
101
-
102
- ch.close
103
- end
104
- end
105
- end
106
-
107
- context "with manual acknowledgement mode" do
108
- let(:queue_name) { "bunny.basic_consume#{rand}" }
109
-
110
- it "register a consumer with manual acknowledgements mode" do
111
- delivered_keys = []
112
- delivered_data = []
113
-
114
- t = Thread.new do
115
- ch = connection.create_channel
116
- q = ch.queue(queue_name, auto_delete: true, durable: false)
117
- q.subscribe(exclusive: false, manual_ack: true) do |delivery_info, properties, payload|
118
- delivered_keys << delivery_info.routing_key
119
- delivered_data << payload
120
-
121
- ch.ack(delivery_info.delivery_tag)
122
- end
123
- end
124
- t.abort_on_exception = true
125
- sleep 0.5
126
-
127
- ch = connection.create_channel
128
- x = ch.default_exchange
129
- x.publish("hello", routing_key: queue_name)
130
-
131
- sleep 0.7
132
- expect(delivered_keys).to include(queue_name)
133
- expect(delivered_data).to include("hello")
134
-
135
- expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
136
-
137
- ch.close
138
- end
139
- end
140
-
141
- ENV.fetch("RUNS", 20).to_i.times do |i|
142
- context "with a queue that already has messages (take #{i})" do
143
- let(:queue_name) { "bunny.basic_consume#{rand}" }
144
-
145
- it "registers the consumer" do
146
- delivered_keys = []
147
- delivered_data = []
148
-
149
- ch = connection.create_channel
150
- q = ch.queue(queue_name, auto_delete: true, durable: false)
151
- x = ch.default_exchange
152
- 100.times do
153
- x.publish("hello", routing_key: queue_name)
154
- end
155
-
156
- sleep 0.7
157
- expect(q.message_count).to be > 50
158
-
159
- t = Thread.new do
160
- ch = connection.create_channel
161
- q = ch.queue(queue_name, auto_delete: true, durable: false)
162
- q.subscribe(exclusive: false, manual_ack: false) do |delivery_info, properties, payload|
163
- delivered_keys << delivery_info.routing_key
164
- delivered_data << payload
165
- end
166
- end
167
- t.abort_on_exception = true
168
- sleep 0.5
169
-
170
- expect(delivered_keys).to include(queue_name)
171
- expect(delivered_data).to include("hello")
172
-
173
- expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
174
-
175
- ch.close
176
- end
177
- end
178
- end # 20.times
179
-
180
-
181
- context "after consumer pool has already been shut down" do
182
- let(:queue_name) { "bunny.basic_consume#{rand}" }
183
-
184
- it "registers the consumer" do
185
- delivered_keys = []
186
- delivered_data = []
187
-
188
- t = Thread.new do
189
- ch = connection.create_channel
190
- q = ch.queue(queue_name)
191
-
192
- c1 = q.subscribe(exclusive: false, manual_ack: false, block: false) do |delivery_info, properties, payload|
193
- end
194
- c1.cancel
195
-
196
- c2 = q.subscribe(exclusive: false, manual_ack: false, block: false) do |delivery_info, properties, payload|
197
- delivered_keys << delivery_info.routing_key
198
- delivered_data << payload
199
- end
200
- c2.cancel
201
-
202
- q.subscribe(exclusive: false, manual_ack: false, block: true) do |delivery_info, properties, payload|
203
- delivered_keys << delivery_info.routing_key
204
- delivered_data << payload
205
- end
206
- end
207
- t.abort_on_exception = true
208
- sleep 0.5
209
-
210
- ch = connection.create_channel
211
- x = ch.default_exchange
212
- x.publish("hello", routing_key: queue_name)
213
-
214
- sleep 0.7
215
- expect(delivered_keys).to include(queue_name)
216
- expect(delivered_data).to include("hello")
217
-
218
- expect(ch.queue(queue_name).message_count).to eq 0
219
-
220
- ch.queue_delete(queue_name)
221
- ch.close
222
- end
223
- end
224
-
225
-
226
- context "with uncaught exceptions in delivery handler" do
227
- context "and defined exception handler" do
228
- let(:queue_name) { "bunny.basic_consume#{rand}" }
229
-
230
- it "uses exception handler" do
231
- caught = nil
232
- t = Thread.new do
233
- ch = connection.create_channel
234
- q = ch.queue(queue_name, auto_delete: true, durable: false)
235
-
236
- ch.on_uncaught_exception do |e, consumer|
237
- caught = e
238
- end
239
-
240
- q.subscribe(exclusive: false, manual_ack: false) do |delivery_info, properties, payload|
241
- raise RuntimeError.new(queue_name)
242
- end
243
- end
244
- t.abort_on_exception = true
245
- sleep 0.5
246
-
247
- ch = connection.create_channel
248
- x = ch.default_exchange
249
- x.publish("hello", routing_key: queue_name)
250
- sleep 0.5
251
-
252
- expect(caught.message).to eq queue_name
253
-
254
- ch.close
255
- end
256
- end
257
-
258
-
259
- context "and default exception handler" do
260
- let(:queue_name) { "bunny.basic_consume#{rand}" }
261
-
262
- it "uses exception handler" do
263
- caughts = []
264
- t = Thread.new do
265
- allow(connection.logger).to receive(:error) { |x| caughts << x }
266
-
267
- ch = connection.create_channel
268
- q = ch.queue(queue_name, auto_delete: true, durable: false)
269
-
270
- q.subscribe(exclusive: false, manual_ack: false) do |delivery_info, properties, payload|
271
- raise RuntimeError.new(queue_name)
272
- end
273
- end
274
- t.abort_on_exception = true
275
- sleep 0.5
276
-
277
- ch = connection.create_channel
278
- x = ch.default_exchange
279
- 5.times { x.publish("hello", routing_key: queue_name) }
280
- sleep 1.5
281
-
282
- expect(caughts.size).to eq(5)
283
-
284
- ch.close
285
- end
286
- end
287
-
288
-
289
- context "with a single consumer" do
290
- let(:queue_name) { "bunny.basic_consume#{rand}" }
291
-
292
- it "provides delivery tag access" do
293
- delivery_tags = SortedSet.new
294
-
295
- cch = connection.create_channel
296
- q = cch.queue(queue_name, auto_delete: true, durable: false)
297
- q.subscribe(exclusive: false, manual_ack: false) do |delivery_info, properties, payload|
298
- delivery_tags << delivery_info.delivery_tag
299
- end
300
- sleep 0.5
301
-
302
- ch = connection.create_channel
303
- x = ch.default_exchange
304
- 100.times do
305
- x.publish("hello", routing_key: queue_name)
306
- end
307
-
308
- sleep 1.0
309
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
310
-
311
- expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
312
-
313
- ch.close
314
- end
315
- end
316
-
317
-
318
- context "with multiple consumers on the same channel" do
319
- let(:queue_name) { "bunny.basic_consume#{rand}" }
320
-
321
- it "provides delivery tag access" do
322
- delivery_tags = SortedSet.new
323
-
324
- cch = connection.create_channel
325
- q = cch.queue(queue_name, auto_delete: true, durable: false)
326
-
327
- 7.times do
328
- q.subscribe(exclusive: false, manual_ack: false) do |delivery_info, properties, payload|
329
- delivery_tags << delivery_info.delivery_tag
330
- end
331
- end
332
- sleep 1.0
333
-
334
- ch = connection.create_channel
335
- x = ch.default_exchange
336
- 100.times do
337
- x.publish("hello", routing_key: queue_name)
338
- end
339
-
340
- sleep 1.5
341
- expect(delivery_tags).to eq SortedSet.new(Range.new(1, 100).to_a)
342
-
343
- expect(ch.queue(queue_name, auto_delete: true, durable: false).message_count).to eq 0
344
-
345
- ch.close
346
- end
347
- end
348
- end
349
- end # describe