amqp 0.8.0.rc13 → 0.8.0.rc14
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -1
- data/.travis.yml +8 -2
- data/.yardopts +1 -0
- data/CHANGELOG +9 -0
- data/Gemfile +17 -11
- data/README.md +26 -16
- data/amqp.gemspec +2 -2
- data/bin/ci/before_build.sh +21 -0
- data/docs/08Migration.textile +199 -5
- data/docs/AMQP091ModelExplained.textile +322 -0
- data/docs/Bindings.textile +24 -4
- data/docs/Clustering.textile +1 -1
- data/docs/ConnectingToTheBroker.textile +98 -82
- data/docs/ConnectionEncryptionWithTLS.textile +65 -5
- data/docs/DocumentationGuidesIndex.textile +93 -13
- data/docs/Durability.textile +1 -1
- data/docs/ErrorHandling.textile +458 -94
- data/docs/Exchanges.textile +901 -87
- data/docs/GettingStarted.textile +278 -143
- data/docs/PatternsAndUseCases.textile +420 -0
- data/docs/Queues.textile +730 -178
- data/docs/RabbitMQVersions.textile +18 -3
- data/docs/RunningTests.textile +1 -1
- data/docs/TestingWithEventedSpec.textile +121 -0
- data/docs/Troubleshooting.textile +15 -1
- data/docs/VendorSpecificExtensions.textile +1 -1
- data/docs/diagrams/001_hello_world_example_routing.png +0 -0
- data/docs/diagrams/002_blabbr_example_routing.png +0 -0
- data/docs/diagrams/003_weathr_example_routing.png +0 -0
- data/docs/diagrams/004_fanout_exchange.png +0 -0
- data/docs/diagrams/005_direct_exchange.png +0 -0
- data/docs/diagrams/redhat/direct_exchange.png +0 -0
- data/docs/diagrams/redhat/fanout_exchange.png +0 -0
- data/docs/diagrams/redhat/topic_exchange.png +0 -0
- data/examples/error_handling/automatic_recovery_of_channel_and_queues.rb +50 -0
- data/examples/error_handling/automatically_recovering_hello_world_consumer.rb +51 -0
- data/examples/error_handling/automatically_recovering_hello_world_consumer_that_uses_a_server_named_queue.rb +51 -0
- data/examples/error_handling/basic_connection_failover.rb +22 -0
- data/examples/error_handling/channel_level_exception.rb +9 -2
- data/examples/error_handling/connection_level_exception.rb +8 -1
- data/examples/error_handling/connection_level_exception_with_objects.rb +49 -0
- data/examples/error_handling/connection_loss_handler.rb +1 -5
- data/examples/error_handling/hello_world_producer.rb +43 -0
- data/examples/error_handling/insufficient_permissions.rb +54 -0
- data/examples/error_handling/manual_connection_and_channel_recovery.rb +71 -0
- data/examples/error_handling/queue_exclusivity_violation.rb +41 -0
- data/examples/error_handling/queue_name_violation.rb +31 -0
- data/examples/exchanges/autodeletion_of_exchanges.rb +1 -4
- data/examples/guides/queues/01a_declaring_a_server_named_queue_using_queue_constructor.rb +7 -8
- data/examples/guides/queues/01b_declaring_a_queue_using_queue_constructor.rb +7 -8
- data/examples/guides/queues/02a_declaring_a_durable_shared_queue.rb +5 -8
- data/examples/guides/queues/02b_declaring_a_durable_shared_queue.rb +5 -8
- data/examples/guides/queues/03a_declaring_a_temporary_exclusive_queue.rb +7 -8
- data/examples/guides/queues/04_bind_a_queue_using_exchange_instance.rb +9 -10
- data/examples/guides/queues/05_bind_a_queue_using_exchange_name.rb +8 -10
- data/examples/guides/queues/06_subscribe_to_receive_messages.rb +10 -12
- data/examples/guides/queues/07_fetch_a_message_from_the_queue.rb +14 -14
- data/examples/guides/queues/08_unsubscribing_a_consumer.rb +13 -16
- data/examples/guides/queues/09_unbinding_from_exchange.rb +16 -22
- data/examples/guides/queues/10_purge_a_queue.rb +13 -18
- data/examples/guides/queues/11_deleting_a_queue.rb +14 -19
- data/examples/guides/queues/12_objects_that_consume_messages.rb +69 -0
- data/examples/guides/queues/13_objects_that_consume_messages_take_two.rb +89 -0
- data/examples/hello_world.rb +1 -3
- data/examples/hello_world_with_an_empty_string.rb +5 -6
- data/examples/inspecting_server_information.rb +45 -0
- data/examples/issues/issue_93.rb +23 -0
- data/examples/issues/issue_94.rb +23 -0
- data/examples/patterns/command/consumer.rb +45 -0
- data/examples/patterns/command/producer.rb +26 -0
- data/examples/patterns/request_reply/client.rb +29 -0
- data/examples/patterns/request_reply/server.rb +26 -0
- data/examples/publishing/publishing_a_one_off_message.rb +6 -4
- data/examples/publishing/returned_messages.rb +2 -10
- data/examples/queues/accessing_message_metadata.rb +15 -13
- data/examples/queues/queue_status.rb +12 -15
- data/examples/routing/fanout_routing.rb +33 -0
- data/examples/routing/headers_routing.rb +17 -15
- data/examples/routing/round_robin_with_direct_exchange.rb +39 -0
- data/examples/routing/round_robin_with_the_default_exchange.rb +38 -0
- data/examples/routing/unroutable_mandatory_message_is_returned.rb +33 -0
- data/examples/routing/weather_updates.rb +15 -20
- data/examples/tls/using_tls.rb +41 -0
- data/lib/amqp/bit_set.rb +80 -0
- data/lib/amqp/broker.rb +72 -0
- data/lib/amqp/channel.rb +93 -13
- data/lib/amqp/client.rb +11 -22
- data/lib/amqp/compatibility/ruby187_patchlevel_check.rb +2 -0
- data/lib/amqp/connection.rb +2 -3
- data/lib/amqp/consumer.rb +208 -0
- data/lib/amqp/deprecated/fork.rb +2 -0
- data/lib/amqp/deprecated/mq.rb +2 -0
- data/lib/amqp/exchange.rb +6 -4
- data/lib/amqp/extensions/rabbitmq.rb +3 -1
- data/lib/amqp/header.rb +76 -14
- data/lib/amqp/int_allocator.rb +96 -0
- data/lib/amqp/logger.rb +2 -0
- data/lib/amqp/queue.rb +242 -86
- data/lib/amqp/rpc.rb +2 -0
- data/lib/amqp/session.rb +169 -9
- data/lib/amqp/utilities/event_loop_helper.rb +2 -0
- data/lib/amqp/utilities/server_type.rb +2 -0
- data/lib/amqp/version.rb +2 -2
- data/lib/mq.rb +4 -2
- data/lib/mq/logger.rb +3 -1
- data/lib/mq/rpc.rb +3 -1
- data/spec/integration/authentication_spec.rb +17 -10
- data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +1 -1
- data/spec/integration/automatic_recovery_predicate_spec.rb +68 -0
- data/spec/integration/basic_get_spec.rb +2 -1
- data/spec/integration/{extensions/basic_return_spec.rb → basic_return_spec.rb} +2 -1
- data/spec/integration/channel_level_exception_handling_spec.rb +53 -0
- data/spec/integration/connection_level_exception_handling_spec.rb +49 -0
- data/spec/integration/declare_and_immediately_bind_a_server_named_queue_spec.rb +38 -17
- data/spec/integration/declare_one_hundred_server_named_queues_spec.rb +44 -0
- data/spec/integration/direct_exchange_routing_spec.rb +125 -0
- data/spec/integration/exchange_declaration_spec.rb +75 -46
- data/spec/integration/extensions/rabbitmq/publisher_confirmations_spec.rb +180 -0
- data/spec/integration/{workload_distribution_spec.rb → fanout_exchange_routing_spec.rb} +10 -9
- data/spec/integration/headers_exchange_routing_spec.rb +269 -0
- data/spec/integration/hello_world_spec.rb +77 -0
- data/spec/integration/immediate_messages_spec.rb +59 -0
- data/spec/integration/mandatory_messages_spec.rb +52 -0
- data/spec/integration/message_metadata_access_spec.rb +106 -0
- data/spec/integration/multiple_consumers_per_queue_spec.rb +319 -0
- data/spec/integration/ordering_of_published_messages_spec.rb +96 -0
- data/spec/integration/queue_declaration_spec.rb +8 -8
- data/spec/integration/queue_status_spec.rb +66 -0
- data/spec/integration/recovery/per_channel_automatic_recovery_on_graceful_broker_shutdown_spec.rb +76 -0
- data/spec/integration/recovery/per_channel_automatic_recovery_spec.rb +72 -0
- data/spec/integration/redelivery_of_unacknowledged_messages_spec.rb +96 -0
- data/spec/integration/regressions/concurrent_publishing_on_the_same_channel_spec.rb +91 -0
- data/spec/integration/regressions/empty_message_body_spec.rb +56 -0
- data/spec/integration/regressions/issue66_spec.rb +2 -1
- data/spec/integration/reply_queue_communication_spec.rb +2 -1
- data/spec/integration/store_and_forward_spec.rb +4 -3
- data/spec/integration/topic_subscription_spec.rb +2 -1
- data/spec/integration/tx_commit_spec.rb +124 -0
- data/spec/integration/tx_rollback_spec.rb +167 -0
- data/spec/spec_helper.rb +44 -71
- data/spec/unit/amqp/bit_set_spec.rb +127 -0
- data/spec/unit/amqp/channel_id_allocation_spec.rb +40 -0
- data/spec/unit/amqp/connection_spec.rb +4 -2
- data/spec/unit/amqp/int_allocator_spec.rb +116 -0
- metadata +92 -26
- data/CONTRIBUTORS +0 -29
- data/docs/Routing.textile +0 -30
- data/examples/real-world/task-queue/README.textile +0 -3
- data/examples/real-world/task-queue/consumer.rb +0 -27
- data/examples/real-world/task-queue/producer.rb +0 -22
- data/spec/unit/amqp/basic_spec.rb +0 -39
- data/tasks.rb +0 -4
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
include PlatformDetection
|
6
|
+
|
7
|
+
# Only run this for MRI.
|
8
|
+
#
|
9
|
+
# rubinius implementation of ThreadGroup has a bug: it references objects without checking
|
10
|
+
# whether they are alive. So sandbox this test for other Rubies for now. Per discussion with
|
11
|
+
# brixen in #travis, see also https://gist.github.com/1100572.
|
12
|
+
#
|
13
|
+
# JRuby is having weird CI issues, too. Still investigating them. MK.
|
14
|
+
if mri?
|
15
|
+
describe "Concurrent publishing on a shared channel from multiple threads" do
|
16
|
+
|
17
|
+
#
|
18
|
+
# Environment
|
19
|
+
#
|
20
|
+
|
21
|
+
include EventedSpec::AMQPSpec
|
22
|
+
default_options AMQP_OPTS
|
23
|
+
default_timeout 15
|
24
|
+
|
25
|
+
amqp_before do
|
26
|
+
@channel = AMQP::Channel.new
|
27
|
+
@channel.on_error do |ch, close|
|
28
|
+
raise "Channel-level error!: #{close.inspect}"
|
29
|
+
end
|
30
|
+
@channel.connection.on_error do |conn, connection_close|
|
31
|
+
raise "Handling a connection-level exception: #{connection_close.reply_text}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
let(:inputs) do
|
37
|
+
[
|
38
|
+
{ :index=>{:_routing=>530,:_index=>"optimizer",:_type=>"earnings",:_id=>530}},
|
39
|
+
{ :total_conversions=>0,:banked_clicks=>0,:total_earnings=>0,:pending_conversions=>0,:paid_net_earnings=>0,:banked_conversions=>0,:pending_earnings=>0,:optimizer_id=>530,:total_impressions=>0,:banked_earnings=>0,:bounce_count=>0,:time_on_page=>0,:total_clicks=>0,:entrances=>0,:pending_clicks=>0,:paid_earnings=>0},
|
40
|
+
|
41
|
+
{ :index=>{:_routing=>430,:_index=>"optimizer",:_type=>"earnings",:_id=>430}},
|
42
|
+
{ :total_conversions=>1443,:banked_clicks=>882,:total_earnings=>5796.3315841537,:pending_conversions=>22,:paid_net_earnings=>4116.90224486802,:banked_conversions=>1086,:pending_earnings=>257.502767857143,:optimizer_id=>430,:total_impressions=>6370497,:banked_earnings=>122.139339285714,:bounce_count=>6825,:time_on_page=>0,:total_clicks=>38143,:entrances=>12336,:pending_clicks=>1528,:paid_earnings=>5670.78224486798},
|
43
|
+
|
44
|
+
{ :index=>{:_routing=>506,:_index=>"optimizer",:_type=>"earnings",:_id=>506}},
|
45
|
+
{ :total_conversions=>237,:banked_clicks=>232,:total_earnings=>550.6212071428588277,:pending_conversions=>9,:paid_net_earnings=>388.021207142857,:banked_conversions=>225,:pending_earnings=>150.91,:optimizer_id=>506,:total_impressions=>348319,:banked_earnings=>12.92,:bounce_count=>905,:time_on_page=>0,:total_clicks=>4854,:entrances=>1614,:pending_clicks=>1034,:paid_earnings=>537.501207142858},
|
46
|
+
|
47
|
+
{:index=>{:_routing=>345,:_index=>"optimizer",:_type=>"earnings",:_id=>345}},
|
48
|
+
{:total_conversions=>0,:banked_clicks=>0,:total_earnings=>0,:pending_conversions=>0,:paid_net_earnings=>0,:banked_conversions=>0,:pending_earnings=>0,:optimizer_id=>345,:total_impressions=>0,:banked_earnings=>0,:bounce_count=>0,:time_on_page=>0,:total_clicks=>0,:entrances=>0,:pending_clicks=>0,:paid_earnings=>0}
|
49
|
+
]
|
50
|
+
end
|
51
|
+
let(:messages) { inputs.map {|i| MultiJson.encode(i) } * 3 }
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
#
|
56
|
+
# Examples
|
57
|
+
#
|
58
|
+
|
59
|
+
it "DOES NOT result in frames being delivered out of order (no UNEXPECTED_FRAME connection exceptions)" do
|
60
|
+
received_messages = []
|
61
|
+
queue = @channel.queue("amqpgem.tests.concurrent_publishing", :auto_delete => true)
|
62
|
+
exchange = @channel.default_exchange
|
63
|
+
exchange.on_return do |method, header, body|
|
64
|
+
raise "Message was returned: #{method.reply_text}"
|
65
|
+
end
|
66
|
+
|
67
|
+
queue.subscribe do |metadata, payload|
|
68
|
+
received_messages << payload
|
69
|
+
end
|
70
|
+
|
71
|
+
EventMachine.add_timer(2.0) do
|
72
|
+
# ZOMG THREADS!
|
73
|
+
20.times do
|
74
|
+
Thread.new do
|
75
|
+
messages.each do |message|
|
76
|
+
exchange.publish(message, :routing_key => queue.name, :immediate => true, :mandatory => true)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# let it run for several seconds because you know, concurrency issues do not always manifest themselves
|
84
|
+
# immediately. MK.
|
85
|
+
done(14.0) {
|
86
|
+
# we don't care about the exact number of messages sent or received, just the fact that there are
|
87
|
+
# no UNEXPECTED_FRAME connection-level exceptions. MK.
|
88
|
+
}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe "Messages with empty bodies" do
|
6
|
+
|
7
|
+
#
|
8
|
+
# Environment
|
9
|
+
#
|
10
|
+
|
11
|
+
include EventedSpec::AMQPSpec
|
12
|
+
default_options AMQP_OPTS
|
13
|
+
default_timeout 5
|
14
|
+
|
15
|
+
amqp_before do
|
16
|
+
@channel = AMQP::Channel.new
|
17
|
+
@channel.on_error do |ch, close|
|
18
|
+
raise "Channel-level error!: #{close.inspect}"
|
19
|
+
end
|
20
|
+
|
21
|
+
@queue = @channel.queue("", :auto_delete => true)
|
22
|
+
@exchange = @channel.direct("amqpgem.tests.integration.direct.exchange", :auto_delete => true)
|
23
|
+
|
24
|
+
@queue.bind(@exchange, :routing_key => "builds.all")
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
it "can be mixed with any other messages" do
|
30
|
+
mailbox1 = Array.new
|
31
|
+
mailbox2 = Array.new
|
32
|
+
|
33
|
+
consumer1 = AMQP::Consumer.new(@channel, @queue).consume
|
34
|
+
consumer2 = AMQP::Consumer.new(@channel, @queue).consume
|
35
|
+
|
36
|
+
|
37
|
+
consumer1.on_delivery do |metadata, payload|
|
38
|
+
mailbox1 << payload
|
39
|
+
end
|
40
|
+
consumer2.on_delivery do |metadata, payload|
|
41
|
+
mailbox2 << payload
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
EventMachine.add_timer(0.5) do
|
46
|
+
12.times { @exchange.publish("", :routing_key => "builds.all") }
|
47
|
+
12.times { @exchange.publish(".", :routing_key => "all.builds") }
|
48
|
+
12.times { @exchange.publish("", :routing_key => "all.builds") }
|
49
|
+
end
|
50
|
+
|
51
|
+
done(1.5) {
|
52
|
+
mailbox1.size.should == 6
|
53
|
+
mailbox2.size.should == 6
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# encoding: utf-8
|
2
|
+
|
2
3
|
require "spec_helper"
|
3
4
|
|
4
5
|
describe "Store-and-forward routing" do
|
@@ -64,7 +65,7 @@ describe "Store-and-forward routing" do
|
|
64
65
|
end
|
65
66
|
|
66
67
|
# 6 seconds are for Rubinius, it is surprisingly slow on this workload
|
67
|
-
done(
|
68
|
+
done(6.0) {
|
68
69
|
number_of_received_messages.should == expected_number_of_messages
|
69
70
|
@queue.unsubscribe
|
70
71
|
}
|
@@ -84,7 +85,7 @@ describe "Store-and-forward routing" do
|
|
84
85
|
end
|
85
86
|
|
86
87
|
# 6 seconds are for Rubinius, it is surprisingly slow on this workload
|
87
|
-
done(
|
88
|
+
done(6.0) {
|
88
89
|
number_of_received_messages.should == expected_number_of_messages
|
89
90
|
@queue.unsubscribe
|
90
91
|
}
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
|
5
|
+
describe "Messages published before AMQP transaction commits" do
|
6
|
+
|
7
|
+
#
|
8
|
+
# Environment
|
9
|
+
#
|
10
|
+
|
11
|
+
include EventedSpec::AMQPSpec
|
12
|
+
default_timeout 1.5
|
13
|
+
|
14
|
+
amqp_before do
|
15
|
+
@producer_channel = AMQP::Channel.new
|
16
|
+
@consumer_channel = AMQP::Channel.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# ...
|
20
|
+
|
21
|
+
|
22
|
+
#
|
23
|
+
# Examples
|
24
|
+
#
|
25
|
+
|
26
|
+
it "are not accessible to AMQP consumers" do
|
27
|
+
exchange = @producer_channel.fanout("amq.fanout")
|
28
|
+
queue = @consumer_channel.queue("", :exclusive => true)
|
29
|
+
|
30
|
+
queue.bind(exchange).subscribe do |metadata, payload|
|
31
|
+
fail "Consumer received a message before transaction committed"
|
32
|
+
end
|
33
|
+
|
34
|
+
@producer_channel.tx_select
|
35
|
+
EventMachine.add_timer(0.5) do
|
36
|
+
50.times { exchange.publish("before tx.commit") }
|
37
|
+
# @producer_channel.tx_commit
|
38
|
+
end
|
39
|
+
|
40
|
+
done(1.2)
|
41
|
+
end # it
|
42
|
+
end # describe
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
describe "AMQP transaction commit" do
|
48
|
+
|
49
|
+
#
|
50
|
+
# Environment
|
51
|
+
#
|
52
|
+
|
53
|
+
include EventedSpec::AMQPSpec
|
54
|
+
default_timeout 1.5
|
55
|
+
|
56
|
+
amqp_before do
|
57
|
+
@producer_channel = AMQP::Channel.new
|
58
|
+
@consumer_channel = AMQP::Channel.new
|
59
|
+
end
|
60
|
+
|
61
|
+
# ...
|
62
|
+
|
63
|
+
|
64
|
+
#
|
65
|
+
# Examples
|
66
|
+
#
|
67
|
+
|
68
|
+
it "causes messages published since the last tx.select to be delivered to AMQP consumers" do
|
69
|
+
exchange = @producer_channel.fanout("amq.fanout")
|
70
|
+
queue = @consumer_channel.queue("", :exclusive => true)
|
71
|
+
|
72
|
+
queue.bind(exchange).subscribe { |metadata, payload| done }
|
73
|
+
|
74
|
+
@producer_channel.tx_select
|
75
|
+
EventMachine.add_timer(0.5) do
|
76
|
+
50.times { exchange.publish("before tx.commit") }
|
77
|
+
@producer_channel.tx_commit
|
78
|
+
end
|
79
|
+
|
80
|
+
done(1.2)
|
81
|
+
end # it
|
82
|
+
end # describe
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
describe "AMQP transaction commit attempt on a non-transactional channel" do
|
88
|
+
|
89
|
+
#
|
90
|
+
# Environment
|
91
|
+
#
|
92
|
+
|
93
|
+
include EventedSpec::AMQPSpec
|
94
|
+
default_timeout 1.5
|
95
|
+
|
96
|
+
amqp_before do
|
97
|
+
@producer_channel = AMQP::Channel.new
|
98
|
+
@consumer_channel = AMQP::Channel.new
|
99
|
+
end
|
100
|
+
|
101
|
+
# ...
|
102
|
+
|
103
|
+
|
104
|
+
#
|
105
|
+
# Examples
|
106
|
+
#
|
107
|
+
|
108
|
+
it "causes channel-level exception" do
|
109
|
+
exchange = @producer_channel.fanout("amq.fanout")
|
110
|
+
queue = @consumer_channel.queue("", :exclusive => true)
|
111
|
+
|
112
|
+
queue.bind(exchange).subscribe do |metadata, payload|
|
113
|
+
fail "Consumer received a message before transaction committed"
|
114
|
+
end
|
115
|
+
|
116
|
+
@producer_channel.on_error do |ch, channel_close|
|
117
|
+
puts "#{channel_close.reply_text}"
|
118
|
+
done
|
119
|
+
end
|
120
|
+
EventMachine.add_timer(0.5) { @producer_channel.tx_commit }
|
121
|
+
|
122
|
+
done(1.2)
|
123
|
+
end # it
|
124
|
+
end # describe
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
|
5
|
+
describe "AMQP transaction rollback" do
|
6
|
+
|
7
|
+
#
|
8
|
+
# Environment
|
9
|
+
#
|
10
|
+
|
11
|
+
include EventedSpec::AMQPSpec
|
12
|
+
default_timeout 3.5
|
13
|
+
|
14
|
+
amqp_before do
|
15
|
+
@producer_channel = AMQP::Channel.new
|
16
|
+
@consumer_channel = AMQP::Channel.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# ...
|
20
|
+
|
21
|
+
|
22
|
+
#
|
23
|
+
# Examples
|
24
|
+
#
|
25
|
+
|
26
|
+
it "voids messages published since the last tx.select" do
|
27
|
+
exchange = @producer_channel.fanout("amq.fanout")
|
28
|
+
queue = @consumer_channel.queue("", :exclusive => true)
|
29
|
+
|
30
|
+
queue.bind(exchange).subscribe do |metadata, payload|
|
31
|
+
fail "Consumer received a message before transaction committed"
|
32
|
+
end
|
33
|
+
|
34
|
+
@producer_channel.tx_select
|
35
|
+
EventMachine.add_timer(0.5) do
|
36
|
+
50.times { exchange.publish("before tx.commit") }
|
37
|
+
@producer_channel.tx_rollback
|
38
|
+
end
|
39
|
+
|
40
|
+
done(2.5)
|
41
|
+
end # it
|
42
|
+
end # describe
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
describe "AMQP connection closure that follows tx.select" do
|
48
|
+
|
49
|
+
#
|
50
|
+
# Environment
|
51
|
+
#
|
52
|
+
|
53
|
+
include EventedSpec::AMQPSpec
|
54
|
+
default_timeout 3.5
|
55
|
+
|
56
|
+
amqp_before do
|
57
|
+
@producer_channel = AMQP::Channel.new
|
58
|
+
@consumer_channel = AMQP::Channel.new
|
59
|
+
end
|
60
|
+
|
61
|
+
# ...
|
62
|
+
|
63
|
+
|
64
|
+
#
|
65
|
+
# Examples
|
66
|
+
#
|
67
|
+
|
68
|
+
it "voids messages published since the last tx.select" do
|
69
|
+
exchange = @producer_channel.fanout("amq.fanout")
|
70
|
+
queue = @consumer_channel.queue("", :exclusive => true)
|
71
|
+
|
72
|
+
queue.bind(exchange).subscribe do |metadata, payload|
|
73
|
+
fail "Consumer received a message before transaction committed"
|
74
|
+
end
|
75
|
+
|
76
|
+
@producer_channel.tx_select
|
77
|
+
EventMachine.add_timer(0.5) do
|
78
|
+
3.times { exchange.publish("before tx.commit") }
|
79
|
+
@producer_channel.connection.close
|
80
|
+
end
|
81
|
+
|
82
|
+
done(2.5)
|
83
|
+
end # it
|
84
|
+
end # describe
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
describe "AMQP channel closure that follows tx.select" do
|
90
|
+
|
91
|
+
#
|
92
|
+
# Environment
|
93
|
+
#
|
94
|
+
|
95
|
+
include EventedSpec::AMQPSpec
|
96
|
+
default_timeout 3.5
|
97
|
+
|
98
|
+
amqp_before do
|
99
|
+
@producer_channel = AMQP::Channel.new
|
100
|
+
@consumer_channel = AMQP::Channel.new
|
101
|
+
end
|
102
|
+
|
103
|
+
# ...
|
104
|
+
|
105
|
+
|
106
|
+
#
|
107
|
+
# Examples
|
108
|
+
#
|
109
|
+
|
110
|
+
it "voids messages published since the last tx.select" do
|
111
|
+
exchange = @producer_channel.fanout("amq.fanout")
|
112
|
+
queue = @consumer_channel.queue("", :exclusive => true)
|
113
|
+
|
114
|
+
queue.bind(exchange).subscribe do |metadata, payload|
|
115
|
+
fail "Consumer received a message before transaction committed"
|
116
|
+
end
|
117
|
+
|
118
|
+
@producer_channel.tx_select
|
119
|
+
EventMachine.add_timer(0.5) do
|
120
|
+
3.times { exchange.publish("before tx.commit") }
|
121
|
+
@producer_channel.close
|
122
|
+
end
|
123
|
+
|
124
|
+
done(2.5)
|
125
|
+
end # it
|
126
|
+
end # describe
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
describe "AMQP transaction rollback attempt on a non-transactional channel" do
|
131
|
+
|
132
|
+
#
|
133
|
+
# Environment
|
134
|
+
#
|
135
|
+
|
136
|
+
include EventedSpec::AMQPSpec
|
137
|
+
default_timeout 3.5
|
138
|
+
|
139
|
+
amqp_before do
|
140
|
+
@producer_channel = AMQP::Channel.new
|
141
|
+
@consumer_channel = AMQP::Channel.new
|
142
|
+
end
|
143
|
+
|
144
|
+
# ...
|
145
|
+
|
146
|
+
|
147
|
+
#
|
148
|
+
# Examples
|
149
|
+
#
|
150
|
+
|
151
|
+
it "causes channel-level exception" do
|
152
|
+
exchange = @producer_channel.fanout("amq.fanout")
|
153
|
+
queue = @consumer_channel.queue("", :exclusive => true)
|
154
|
+
|
155
|
+
queue.bind(exchange).subscribe do |metadata, payload|
|
156
|
+
fail "Consumer received a message before transaction committed"
|
157
|
+
end
|
158
|
+
|
159
|
+
@producer_channel.on_error do |ch, channel_close|
|
160
|
+
puts "#{channel_close.reply_text}"
|
161
|
+
done
|
162
|
+
end
|
163
|
+
EventMachine.add_timer(0.5) { @producer_channel.tx_rollback }
|
164
|
+
|
165
|
+
done(2.5)
|
166
|
+
end # it
|
167
|
+
end # describe
|