amqp 1.0.0.pre2 → 1.0.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.
- data/.travis.yml +3 -0
- data/README.md +80 -72
- data/amqp.gemspec +5 -13
- data/docs/08Migration.textile +4 -0
- data/docs/AMQP091ModelExplained.textile +6 -1
- data/docs/Bindings.textile +4 -0
- data/docs/Clustering.textile +4 -0
- data/docs/ConnectingToTheBroker.textile +4 -0
- data/docs/ConnectionEncryptionWithTLS.textile +4 -0
- data/docs/DocumentationGuidesIndex.textile +4 -0
- data/docs/Durability.textile +4 -0
- data/docs/ErrorHandling.textile +4 -0
- data/docs/Exchanges.textile +4 -0
- data/docs/GettingStarted.textile +4 -0
- data/docs/PatternsAndUseCases.textile +4 -1
- data/docs/Queues.textile +4 -0
- data/docs/RabbitMQVersions.textile +4 -0
- data/docs/RunningTests.textile +4 -0
- data/docs/TestingWithEventedSpec.textile +4 -0
- data/docs/Troubleshooting.textile +4 -0
- data/docs/VendorSpecificExtensions.textile +4 -0
- data/examples/error_handling/automatic_recovery_of_channel_and_queues.rb +1 -1
- data/examples/error_handling/automatically_recovering_hello_world_consumer.rb +1 -1
- data/examples/error_handling/automatically_recovering_hello_world_consumer_that_uses_a_server_named_queue.rb +1 -1
- data/examples/error_handling/connection_level_exception.rb +1 -1
- data/examples/error_handling/connection_level_exception_with_objects.rb +1 -1
- data/examples/error_handling/connection_loss_handler.rb +4 -3
- data/examples/error_handling/hello_world_producer.rb +1 -1
- data/examples/error_handling/manual_connection_and_channel_recovery.rb +1 -1
- data/examples/extensions/rabbitmq/publisher_confirmations_with_transient_messages.rb +1 -1
- data/examples/extensions/rabbitmq/using_alternate_exchanges.rb +1 -1
- data/examples/guides/getting_started/01_hello_world.rb +1 -1
- data/examples/guides/getting_started/02_hello_world_dslified.rb +1 -1
- data/examples/hello_world.rb +1 -1
- data/examples/hello_world_with_an_empty_string.rb +1 -1
- data/examples/hello_world_with_eventmachine_in_a_separate_thread.rb +2 -2
- data/examples/hello_world_with_large_payload.rb +41 -41
- data/examples/patterns/request_reply/client.rb +1 -2
- data/examples/patterns/request_reply/server.rb +0 -1
- data/examples/publishing/returned_messages.rb +1 -1
- data/examples/queues/accessing_message_metadata.rb +1 -1
- data/examples/queues/cancel_default_consumer.rb +1 -1
- data/lib/amqp/channel.rb +34 -16
- data/lib/amqp/client.rb +2 -2
- data/lib/amqp/connection.rb +2 -1
- data/lib/amqp/consumer.rb +2 -2
- data/lib/amqp/exceptions.rb +11 -2
- data/lib/amqp/exchange.rb +5 -5
- data/lib/amqp/queue.rb +51 -26
- data/lib/amqp/session.rb +5 -5
- data/lib/amqp/version.rb +1 -1
- data/spec/integration/basic_get_spec.rb +82 -27
- data/spec/integration/basic_return_spec.rb +3 -3
- data/spec/integration/channel_level_exception_with_multiple_channels_spec.rb +0 -1
- data/spec/integration/exchange_declaration_spec.rb +71 -102
- data/spec/integration/extensions/rabbitmq/publisher_confirmations_spec.rb +1 -1
- data/spec/integration/fanout_exchange_routing_spec.rb +1 -1
- data/spec/integration/multiple_consumers_per_queue_spec.rb +3 -160
- data/spec/integration/queue_redeclaration_with_incompatible_attributes_spec.rb +25 -12
- data/spec/integration/regressions/concurrent_publishing_on_the_same_channel_spec.rb +1 -1
- data/spec/integration/remove_individual_binding_spec.rb +51 -0
- data/spec/integration/reply_queue_communication_spec.rb +1 -2
- data/spec/integration/store_and_forward_spec.rb +6 -9
- data/spec/integration/topic_subscription_spec.rb +5 -4
- data/spec/spec_helper.rb +8 -2
- data/spec/unit/amqp/connection_spec.rb +3 -1
- metadata +93 -109
- data/spec/integration/immediate_messages_spec.rb +0 -59
@@ -38,11 +38,11 @@ describe "Message published as mandatory" do
|
|
38
38
|
@exchange.on_return do |basic_return, header, body|
|
39
39
|
returned_messages << basic_return.reply_text
|
40
40
|
end
|
41
|
-
(1..10).to_a.each { |m| @exchange.publish(m, :
|
41
|
+
(1..10).to_a.each { |m| @exchange.publish(m, :mandatory => true) }
|
42
42
|
|
43
43
|
done(1.0) {
|
44
|
-
returned_messages.should == Array.new(10) { "
|
44
|
+
returned_messages.should == Array.new(10) { "NO_ROUTE" }
|
45
45
|
}
|
46
46
|
end
|
47
47
|
end
|
48
|
-
end
|
48
|
+
end
|
@@ -127,27 +127,14 @@ describe AMQP::Channel do
|
|
127
127
|
end # context
|
128
128
|
|
129
129
|
|
130
|
-
context "when exchange name was specified as a blank string" do
|
131
|
-
it 'returns direct exchange with server-generated name' do
|
132
|
-
pending <<-EOF
|
133
|
-
This has to be fixed in RabbitMQ first
|
134
|
-
https://bugzilla.rabbitmq.com/show_bug.cgi?id=23509
|
135
|
-
EOF
|
136
|
-
@channel.direct("") do |exchange|
|
137
|
-
exchange.name.should_not be_empty
|
138
|
-
done
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end # context
|
142
|
-
|
143
|
-
|
144
130
|
context "when passive option is used" do
|
145
131
|
context "and exchange with given name already exists" do
|
146
132
|
it "silently returns" do
|
147
|
-
name
|
133
|
+
name = "a_new_direct_exchange declared at #{Time.now.to_i}"
|
134
|
+
channel = AMQP::Channel.new
|
148
135
|
|
149
|
-
original_exchange =
|
150
|
-
exchange =
|
136
|
+
original_exchange = channel.direct(name)
|
137
|
+
exchange = channel.direct(name, :passive => true)
|
151
138
|
|
152
139
|
exchange.should == original_exchange
|
153
140
|
|
@@ -157,13 +144,16 @@ describe AMQP::Channel do
|
|
157
144
|
|
158
145
|
context "and exchange with given name DOES NOT exist" do
|
159
146
|
it "raises an exception" do
|
160
|
-
|
147
|
+
channel = AMQP::Channel.new
|
148
|
+
channel.on_error do |ch, channel_close|
|
149
|
+
@error_code = channel_close.reply_code
|
150
|
+
end
|
161
151
|
|
162
|
-
|
163
|
-
exchange = @channel.direct("direct exchange declared at #{Time.now.to_i}", :passive => true)
|
164
|
-
}.to raise_error
|
152
|
+
exchange = channel.direct("direct exchange declared at #{Time.now.to_i}", :passive => true)
|
165
153
|
|
166
|
-
done
|
154
|
+
done(0.5) {
|
155
|
+
@error_code.should == 404
|
156
|
+
}
|
167
157
|
end # it
|
168
158
|
end # context
|
169
159
|
end # context
|
@@ -223,27 +213,16 @@ describe AMQP::Channel do
|
|
223
213
|
|
224
214
|
context "when exchange is re-declared with parameters different from original declaration" do
|
225
215
|
it "raises an exception" do
|
226
|
-
|
216
|
+
channel = AMQP::Channel.new
|
217
|
+
channel.direct("previously.declared.durable.direct.exchange", :durable => true)
|
227
218
|
|
228
219
|
expect {
|
229
|
-
|
220
|
+
channel.direct("previously.declared.durable.direct.exchange", :durable => false)
|
230
221
|
}.to raise_error(AMQP::IncompatibleOptionsError)
|
231
222
|
|
232
223
|
done
|
233
224
|
end # it
|
234
225
|
end # context
|
235
|
-
|
236
|
-
context "when exchange is re-declared with irrelevent parameters different from original declaration" do
|
237
|
-
it "doesn't raise an exception" do
|
238
|
-
@channel.direct("previously.declared.durable.direct.exchange", :durable => true)
|
239
|
-
|
240
|
-
expect {
|
241
|
-
@channel.direct("previously.declared.durable.direct.exchange", :durable => true, :header => {:random => 'stuff' })
|
242
|
-
}.to_not raise_error(AMQP::IncompatibleOptionsError)
|
243
|
-
|
244
|
-
done
|
245
|
-
end # it
|
246
|
-
end # context
|
247
226
|
end # describe
|
248
227
|
|
249
228
|
|
@@ -287,12 +266,17 @@ describe AMQP::Channel do
|
|
287
266
|
end
|
288
267
|
|
289
268
|
context "and exchange with given name DOES NOT exist" do
|
290
|
-
it "
|
291
|
-
|
269
|
+
it "results in a channel exception" do
|
270
|
+
channel = AMQP::Channel.new
|
271
|
+
channel.on_error do |ch, channel_close|
|
272
|
+
@error_code = channel_close.reply_code
|
273
|
+
end
|
292
274
|
|
293
|
-
|
294
|
-
|
295
|
-
|
275
|
+
exchange = channel.fanout("fanout exchange declared at #{Time.now.to_i}", :passive => true)
|
276
|
+
|
277
|
+
done(0.5) {
|
278
|
+
@error_code.should == 404
|
279
|
+
}
|
296
280
|
|
297
281
|
done
|
298
282
|
end # it
|
@@ -354,10 +338,11 @@ describe AMQP::Channel do
|
|
354
338
|
|
355
339
|
context "when exchange is re-declared with parameters different from original declaration" do
|
356
340
|
it "raises an exception" do
|
357
|
-
|
341
|
+
channel = AMQP::Channel.new
|
342
|
+
channel.fanout("previously.declared.durable.topic.exchange", :durable => true)
|
358
343
|
|
359
344
|
expect {
|
360
|
-
|
345
|
+
channel.fanout("previously.declared.durable.topic.exchange", :durable => false)
|
361
346
|
}.to raise_error(AMQP::IncompatibleOptionsError)
|
362
347
|
|
363
348
|
done
|
@@ -377,7 +362,7 @@ describe AMQP::Channel do
|
|
377
362
|
exchange.name.should == name
|
378
363
|
|
379
364
|
done
|
380
|
-
end
|
365
|
+
end # it
|
381
366
|
end # context
|
382
367
|
|
383
368
|
context "when exchange name is omitted" do
|
@@ -387,7 +372,7 @@ describe AMQP::Channel do
|
|
387
372
|
exchange.name.should_not == "amq.topic2"
|
388
373
|
|
389
374
|
done
|
390
|
-
end
|
375
|
+
end # it
|
391
376
|
end # context
|
392
377
|
|
393
378
|
context "when passive option is used" do
|
@@ -402,20 +387,23 @@ describe AMQP::Channel do
|
|
402
387
|
|
403
388
|
done
|
404
389
|
end # it
|
405
|
-
end
|
390
|
+
end # context
|
406
391
|
|
407
392
|
context "and exchange with given name DOES NOT exist" do
|
408
|
-
it "
|
409
|
-
|
393
|
+
it "results in a channel exception" do
|
394
|
+
channel = AMQP::Channel.new
|
395
|
+
channel.on_error do |ch, channel_close|
|
396
|
+
@error_code = channel_close.reply_code
|
397
|
+
end
|
410
398
|
|
411
|
-
|
412
|
-
exchange = @channel.topic("topic exchange declared at #{Time.now.to_i}", :passive => true)
|
413
|
-
}.to raise_error
|
399
|
+
exchange = channel.topic("topic exchange declared at #{Time.now.to_i}", :passive => true)
|
414
400
|
|
415
|
-
done
|
401
|
+
done(0.5) {
|
402
|
+
@error_code.should == 404
|
403
|
+
}
|
416
404
|
end # it
|
417
405
|
end # context
|
418
|
-
end
|
406
|
+
end
|
419
407
|
|
420
408
|
|
421
409
|
context "when exchange is declared as durable" do
|
@@ -470,16 +458,14 @@ describe AMQP::Channel do
|
|
470
458
|
end # context
|
471
459
|
|
472
460
|
|
473
|
-
context "when exchange is re-declared with parameters different from original declaration" do
|
461
|
+
context "when exchange is re-declared with parameters different from the original declaration" do
|
474
462
|
amqp_after do
|
475
463
|
done
|
476
464
|
end
|
477
465
|
|
478
466
|
it "raises an exception" do
|
479
467
|
channel = AMQP::Channel.new
|
480
|
-
|
481
468
|
channel.topic("previously.declared.durable.topic.exchange", :durable => true)
|
482
|
-
channel.should be_open
|
483
469
|
|
484
470
|
expect {
|
485
471
|
channel.topic("previously.declared.durable.topic.exchange", :durable => false)
|
@@ -498,7 +484,8 @@ describe AMQP::Channel do
|
|
498
484
|
let(:name) { "new.headers.exchange" }
|
499
485
|
|
500
486
|
it "declares a new headers exchange with that name" do
|
501
|
-
|
487
|
+
channel = AMQP::Channel.new
|
488
|
+
exchange = channel.headers(name)
|
502
489
|
|
503
490
|
exchange.name.should == name
|
504
491
|
|
@@ -512,7 +499,8 @@ describe AMQP::Channel do
|
|
512
499
|
end
|
513
500
|
|
514
501
|
it "uses amq.match" do
|
515
|
-
|
502
|
+
channel = AMQP::Channel.new
|
503
|
+
exchange = channel.headers
|
516
504
|
exchange.name.should == "amq.match"
|
517
505
|
exchange.name.should_not == "amq.headers"
|
518
506
|
|
@@ -523,10 +511,11 @@ describe AMQP::Channel do
|
|
523
511
|
context "when passive option is used" do
|
524
512
|
context "and exchange with given name already exists" do
|
525
513
|
it "silently returns" do
|
526
|
-
name
|
514
|
+
name = "a_new_headers_exchange declared at #{Time.now.to_i}"
|
515
|
+
channel = AMQP::Channel.new
|
527
516
|
|
528
|
-
original_exchange =
|
529
|
-
exchange =
|
517
|
+
original_exchange = channel.headers(name)
|
518
|
+
exchange = channel.headers(name, :passive => true)
|
530
519
|
|
531
520
|
exchange.should == original_exchange
|
532
521
|
|
@@ -536,13 +525,16 @@ describe AMQP::Channel do
|
|
536
525
|
|
537
526
|
context "and exchange with given name DOES NOT exist" do
|
538
527
|
it "raises an exception" do
|
539
|
-
|
528
|
+
channel = AMQP::Channel.new
|
529
|
+
channel.on_error do |ch, channel_close|
|
530
|
+
@error_code = channel_close.reply_code
|
531
|
+
end
|
540
532
|
|
541
|
-
|
542
|
-
exchange = @channel.headers("headers exchange declared at #{Time.now.to_i}", :passive => true)
|
543
|
-
}.to raise_error
|
533
|
+
exchange = channel.headers("headers exchange declared at #{Time.now.to_i}", :passive => true)
|
544
534
|
|
545
|
-
done
|
535
|
+
done(0.5) {
|
536
|
+
@error_code.should == 404
|
537
|
+
}
|
546
538
|
end # it
|
547
539
|
end # context
|
548
540
|
end # context
|
@@ -550,7 +542,8 @@ describe AMQP::Channel do
|
|
550
542
|
|
551
543
|
context "when exchange is declared as durable" do
|
552
544
|
it "returns a new durable headers exchange" do
|
553
|
-
|
545
|
+
channel = AMQP::Channel.new
|
546
|
+
exchange = channel.headers("a_new_durable_headers_exchange", :durable => true)
|
554
547
|
exchange.should be_durable
|
555
548
|
exchange.should_not be_transient
|
556
549
|
|
@@ -561,7 +554,8 @@ describe AMQP::Channel do
|
|
561
554
|
|
562
555
|
context "when exchange is declared as non-durable" do
|
563
556
|
it "returns a new NON-durable headers exchange" do
|
564
|
-
|
557
|
+
channel = AMQP::Channel.new
|
558
|
+
exchange = channel.headers("a_new_non_durable_headers_exchange", :durable => false)
|
565
559
|
exchange.should_not be_durable
|
566
560
|
exchange.should be_transient
|
567
561
|
|
@@ -572,7 +566,8 @@ describe AMQP::Channel do
|
|
572
566
|
|
573
567
|
context "when exchange is declared as auto-deleted" do
|
574
568
|
it "returns a new auto-deleted headers exchange" do
|
575
|
-
|
569
|
+
channel = AMQP::Channel.new
|
570
|
+
exchange = channel.headers("a new auto-deleted headers exchange", :auto_delete => true)
|
576
571
|
|
577
572
|
exchange.should be_auto_deleted
|
578
573
|
done
|
@@ -582,7 +577,8 @@ describe AMQP::Channel do
|
|
582
577
|
|
583
578
|
context "when exchange is declared as auto-deleted" do
|
584
579
|
it "returns a new auto-deleted headers exchange" do
|
585
|
-
|
580
|
+
channel = AMQP::Channel.new
|
581
|
+
exchange = channel.headers("a new non-auto-deleted headers exchange", :auto_delete => false)
|
586
582
|
|
587
583
|
exchange.should_not be_auto_deleted
|
588
584
|
done
|
@@ -592,7 +588,8 @@ describe AMQP::Channel do
|
|
592
588
|
|
593
589
|
context "when exchange is declared without explicit :nowait parameter" do
|
594
590
|
it "is declared with :nowait by default" do
|
595
|
-
|
591
|
+
channel = AMQP::Channel.new
|
592
|
+
exchange = channel.headers("a new non-auto-deleted headers exchange", :auto_delete => false)
|
596
593
|
|
597
594
|
exchange.should_not be_auto_deleted
|
598
595
|
done
|
@@ -606,43 +603,15 @@ describe AMQP::Channel do
|
|
606
603
|
end
|
607
604
|
|
608
605
|
it "raises an exception" do
|
609
|
-
|
606
|
+
channel = AMQP::Channel.new
|
607
|
+
channel.headers("previously.declared.durable.headers.exchange", :durable => true)
|
610
608
|
|
611
609
|
expect {
|
612
|
-
|
610
|
+
channel.headers("previously.declared.durable.headers.exchange", :durable => false)
|
613
611
|
}.to raise_error(AMQP::IncompatibleOptionsError)
|
614
612
|
|
615
613
|
done
|
616
614
|
end # it
|
617
615
|
end # context
|
618
|
-
|
619
|
-
|
620
|
-
context "when exchange is re-declared with parameters different from original declaration on two separate channels" do
|
621
|
-
it "raises an exception" do
|
622
|
-
channel2 = AMQP::Channel.new
|
623
|
-
@channel.headers("previously.declared.durable.headers.exchange", :durable => true)
|
624
|
-
|
625
|
-
channel2.on_error do |ch, channel_close|
|
626
|
-
puts "reply_text: #{channel_close.reply_text}, reply_code: #{channel_close.reply_code}"
|
627
|
-
done
|
628
|
-
end
|
629
|
-
channel2.headers("previously.declared.durable.headers.exchange", :durable => false)
|
630
|
-
end # it
|
631
|
-
end # context
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
context "when exchange is re-declared with type different from original declaration on two separate channels" do
|
636
|
-
it "raises an exception" do
|
637
|
-
channel2 = AMQP::Channel.new
|
638
|
-
@channel.topic("previously.declared.durable.topic.exchange", :durable => true)
|
639
|
-
|
640
|
-
channel2.on_error do |ch, channel_close|
|
641
|
-
puts "reply_text: #{channel_close.reply_text}, reply_code: #{channel_close.reply_code}"
|
642
|
-
done
|
643
|
-
end
|
644
|
-
channel2.headers("previously.declared.durable.topic.exchange", :durable => true)
|
645
|
-
end # it
|
646
|
-
end # context
|
647
616
|
end # describe
|
648
617
|
end # describe AMQP
|
@@ -77,7 +77,7 @@ describe AMQP::Exchange, "of type fanout" do
|
|
77
77
|
end
|
78
78
|
|
79
79
|
# for Rubinius, it is surprisingly slow on this workload
|
80
|
-
done(
|
80
|
+
done(1.5) {
|
81
81
|
[@queue1, @queue2, @queue3].each do |q|
|
82
82
|
@received_messages[q.name].size.should == @expected_number_of_messages[q.name]
|
83
83
|
|
@@ -58,7 +58,7 @@ describe "Multiple non-exclusive consumers per queue" do
|
|
58
58
|
|
59
59
|
EventMachine.add_timer(1.0) do
|
60
60
|
messages.each do |message|
|
61
|
-
exchange.publish(message, :
|
61
|
+
exchange.publish(message, :mandatory => true, :routing_key => queue.name)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -104,7 +104,7 @@ describe "Multiple non-exclusive consumers per queue" do
|
|
104
104
|
|
105
105
|
EventMachine.add_timer(1.0) do
|
106
106
|
messages.each do |message|
|
107
|
-
exchange.publish(message, :
|
107
|
+
exchange.publish(message, :mandatory => true, :routing_key => queue.name)
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -150,7 +150,7 @@ describe "Multiple non-exclusive consumers per queue" do
|
|
150
150
|
|
151
151
|
EventMachine.add_timer(1.0) do
|
152
152
|
messages.each do |message|
|
153
|
-
exchange.publish(message, :
|
153
|
+
exchange.publish(message, :mandatory => true, :routing_key => queue.name)
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
@@ -161,161 +161,4 @@ describe "Multiple non-exclusive consumers per queue" do
|
|
161
161
|
}
|
162
162
|
end # it
|
163
163
|
end # context
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
context "with equal prefetch levels and two consumers cancelled mid-flight" do
|
169
|
-
it "have messages distributed to the only active consumer" do
|
170
|
-
channel = AMQP::Channel.new
|
171
|
-
channel.on_error do |ch, channel_close|
|
172
|
-
raise(channel_close.reply_text)
|
173
|
-
end
|
174
|
-
|
175
|
-
queue = channel.queue("amqpgem.integration.roundrobin.queue1", :auto_delete => true) do
|
176
|
-
consumer1 = AMQP::Consumer.new(channel, queue)
|
177
|
-
consumer2 = AMQP::Consumer.new(channel, queue, "#{queue.name}-consumer-#{rand}-#{Time.now}", false, true)
|
178
|
-
|
179
|
-
consumer1.consume.on_delivery do |basic_deliver, metadata, payload|
|
180
|
-
@consumer1_mailbox << payload
|
181
|
-
end
|
182
|
-
|
183
|
-
consumer2.consume(true).on_delivery do |metadata, payload|
|
184
|
-
@consumer2_mailbox << payload
|
185
|
-
end
|
186
|
-
|
187
|
-
queue.subscribe do |metadata, payload|
|
188
|
-
@consumer3_mailbox << payload
|
189
|
-
end
|
190
|
-
queue.unsubscribe
|
191
|
-
|
192
|
-
consumer2.cancel
|
193
|
-
end
|
194
|
-
|
195
|
-
exchange = channel.default_exchange
|
196
|
-
exchange.on_return do |basic_return, metadata, payload|
|
197
|
-
raise(basic_return.reply_text)
|
198
|
-
end
|
199
|
-
|
200
|
-
EventMachine.add_timer(1.0) do
|
201
|
-
messages.each do |message|
|
202
|
-
exchange.publish(message, :immediate => true, :mandatory => true, :routing_key => queue.name)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
done(5.0) {
|
207
|
-
@consumer1_mailbox.size.should == 100
|
208
|
-
@consumer2_mailbox.size.should == 0
|
209
|
-
@consumer3_mailbox.size.should == 0
|
210
|
-
}
|
211
|
-
end # it
|
212
|
-
end # context
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
unless ENV["CI"]
|
217
|
-
context "with equal prefetch levels, a server-named queue and two consumers cancelled mid-flight" do
|
218
|
-
it "have messages distributed to the only active consumer" do
|
219
|
-
channel = AMQP::Channel.new
|
220
|
-
channel.on_error do |ch, channel_close|
|
221
|
-
raise(channel_close.reply_text)
|
222
|
-
end
|
223
|
-
|
224
|
-
queue = channel.queue("", :auto_delete => true)
|
225
|
-
consumer1 = AMQP::Consumer.new(channel, queue)
|
226
|
-
consumer2 = AMQP::Consumer.new(channel, queue)
|
227
|
-
|
228
|
-
consumer1.consume.on_delivery do |basic_deliver, metadata, payload|
|
229
|
-
@consumer1_mailbox << payload
|
230
|
-
end
|
231
|
-
|
232
|
-
consumer2.consume(true).on_delivery do |metadata, payload|
|
233
|
-
@consumer2_mailbox << payload
|
234
|
-
end
|
235
|
-
queue.subscribe do |metadata, payload|
|
236
|
-
@consumer3_mailbox << payload
|
237
|
-
end
|
238
|
-
queue.unsubscribe
|
239
|
-
consumer2.cancel
|
240
|
-
|
241
|
-
|
242
|
-
exchange = channel.default_exchange
|
243
|
-
exchange.on_return do |basic_return, metadata, payload|
|
244
|
-
raise(basic_return.reply_text)
|
245
|
-
end
|
246
|
-
|
247
|
-
EventMachine.add_timer(1.0) do
|
248
|
-
messages.each do |message|
|
249
|
-
exchange.publish(message, :immediate => true, :mandatory => true, :routing_key => queue.name)
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
done(5.0) {
|
254
|
-
@consumer1_mailbox.size.should == 100
|
255
|
-
@consumer2_mailbox.size.should == 0
|
256
|
-
@consumer3_mailbox.size.should == 0
|
257
|
-
}
|
258
|
-
end # it
|
259
|
-
end # context
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
context "with equal prefetch levels and ALL consumers cancelled mid-flight" do
|
264
|
-
it "returns all immediate messages" do
|
265
|
-
@returned_messages = []
|
266
|
-
|
267
|
-
channel = AMQP::Channel.new
|
268
|
-
channel.on_error do |ch, channel_close|
|
269
|
-
raise(channel_close.reply_text)
|
270
|
-
end
|
271
|
-
|
272
|
-
queue = channel.queue("amqpgem.integration.roundrobin.queue1", :auto_delete => true) do
|
273
|
-
consumer1 = AMQP::Consumer.new(channel, queue)
|
274
|
-
consumer2 = AMQP::Consumer.new(channel, queue, "#{queue.name}-consumer-#{rand}-#{Time.now}", false, true)
|
275
|
-
|
276
|
-
consumer1.consume.on_delivery do |basic_deliver, metadata, payload|
|
277
|
-
@consumer1_mailbox << payload
|
278
|
-
end
|
279
|
-
|
280
|
-
consumer2.consume(true).on_delivery do |metadata, payload|
|
281
|
-
@consumer2_mailbox << payload
|
282
|
-
end
|
283
|
-
|
284
|
-
queue.subscribe do |metadata, payload|
|
285
|
-
@consumer3_mailbox << payload
|
286
|
-
end
|
287
|
-
queue.should be_subscribed
|
288
|
-
queue.unsubscribe
|
289
|
-
queue.should_not be_subscribed
|
290
|
-
|
291
|
-
consumer2.should be_subscribed
|
292
|
-
consumer2.callback.should_not be_nil
|
293
|
-
consumer2.cancel
|
294
|
-
consumer2.should_not be_subscribed
|
295
|
-
consumer2.callback.should be_nil
|
296
|
-
|
297
|
-
consumer1.should be_subscribed
|
298
|
-
consumer1.callback.should_not be_nil
|
299
|
-
consumer1.cancel
|
300
|
-
consumer1.should_not be_subscribed
|
301
|
-
consumer1.callback.should be_nil
|
302
|
-
end
|
303
|
-
|
304
|
-
exchange = channel.default_exchange
|
305
|
-
exchange.on_return do |basic_return, metadata, payload|
|
306
|
-
@returned_messages << payload
|
307
|
-
end
|
308
|
-
|
309
|
-
EventMachine.add_timer(1.0) do
|
310
|
-
messages.each do |message|
|
311
|
-
exchange.publish(message, :immediate => true, :mandatory => true, :routing_key => queue.name)
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
done(6.0) {
|
316
|
-
@returned_messages.size.should == 100
|
317
|
-
}
|
318
|
-
end # it
|
319
|
-
end # context
|
320
|
-
end
|
321
164
|
end # describe
|