amqp 1.0.0.pre2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|