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,180 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
require "amqp/extensions/rabbitmq"
|
6
|
+
|
7
|
+
|
8
|
+
describe "confirm.select" do
|
9
|
+
|
10
|
+
#
|
11
|
+
# Environment
|
12
|
+
#
|
13
|
+
|
14
|
+
include EventedSpec::AMQPSpec
|
15
|
+
include EventedSpec::SpecHelper
|
16
|
+
|
17
|
+
default_options AMQP_OPTS
|
18
|
+
default_timeout 3
|
19
|
+
|
20
|
+
amqp_before do
|
21
|
+
@channel = AMQP::Channel.new
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
context "with :nowait attribute off" do
|
26
|
+
it "results in a confirm.select-ok response" do
|
27
|
+
@channel.confirm_select do |select_ok|
|
28
|
+
done
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
context "with :nowait attribute set" do
|
35
|
+
it "results in NOT confirm.select-ok response" do
|
36
|
+
lambda do
|
37
|
+
@channel.confirm_select(:nowait => true) do
|
38
|
+
fail "Should never be called"
|
39
|
+
end
|
40
|
+
end.should raise_error(ArgumentError, /makes no sense/)
|
41
|
+
|
42
|
+
@channel.confirm_select(:nowait => true)
|
43
|
+
|
44
|
+
done(0.5)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
describe "Publisher confirmation(s)" do
|
53
|
+
|
54
|
+
#
|
55
|
+
# Environment
|
56
|
+
#
|
57
|
+
|
58
|
+
include EventedSpec::AMQPSpec
|
59
|
+
include EventedSpec::SpecHelper
|
60
|
+
|
61
|
+
default_options AMQP_OPTS
|
62
|
+
default_timeout 3
|
63
|
+
|
64
|
+
|
65
|
+
amqp_before do
|
66
|
+
@channel1 = AMQP::Channel.new
|
67
|
+
@channel2 = AMQP::Channel.new
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
context "when messages are transient" do
|
72
|
+
context "and routable" do
|
73
|
+
it "are confirmed as soon as they arrive on all the queues they were routed to" do
|
74
|
+
events = Array.new
|
75
|
+
|
76
|
+
exchange = @channel2.fanout("amqpgem.tests.fanout1", :auto_delete => true)
|
77
|
+
queue = @channel1.queue("", :auto_delete => true).bind(exchange).subscribe do |metadata, payload|
|
78
|
+
events << :basic_delivery
|
79
|
+
end
|
80
|
+
|
81
|
+
@channel2.confirm_select
|
82
|
+
@channel2.on_ack do |basic_ack|
|
83
|
+
events << :basic_ack
|
84
|
+
end
|
85
|
+
exchange.on_return do |basic_return, metadata, payload|
|
86
|
+
fail "Should never happen"
|
87
|
+
end
|
88
|
+
|
89
|
+
EventMachine.add_timer(0.5) do
|
90
|
+
exchange.publish("Hi", :persistent => false, :mandatory => true)
|
91
|
+
end
|
92
|
+
|
93
|
+
done(2.0) do
|
94
|
+
events.should include(:basic_ack)
|
95
|
+
events.should include(:basic_delivery)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
context "and can be delivered immediately" do
|
102
|
+
it "are confirmed as soon as they arrive on all the queues they were routed to" do
|
103
|
+
events = Array.new
|
104
|
+
|
105
|
+
exchange = @channel2.fanout("amqpgem.tests.fanout2", :auto_delete => true)
|
106
|
+
queue = @channel1.queue("", :auto_delete => true).bind(exchange).subscribe do |metadata, payload|
|
107
|
+
events << :basic_delivery
|
108
|
+
end
|
109
|
+
|
110
|
+
@channel2.confirm_select
|
111
|
+
@channel2.on_ack do |basic_ack|
|
112
|
+
events << :basic_ack
|
113
|
+
end
|
114
|
+
exchange.on_return do |basic_return, metadata, payload|
|
115
|
+
fail "Should never happen"
|
116
|
+
end
|
117
|
+
|
118
|
+
EventMachine.add_timer(0.5) do
|
119
|
+
exchange.publish("Hi", :persistent => false, :immediately => true)
|
120
|
+
end
|
121
|
+
|
122
|
+
done(2.0) do
|
123
|
+
events.should include(:basic_ack)
|
124
|
+
events.should include(:basic_delivery)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
context "and NOT routable" do
|
132
|
+
it "are delivered immediately after basic.return" do
|
133
|
+
events = Array.new
|
134
|
+
|
135
|
+
queue = @channel1.queue("", :auto_delete => true)
|
136
|
+
exchange = @channel2.fanout("amqpgem.tests.fanout3", :auto_delete => true)
|
137
|
+
|
138
|
+
@channel2.confirm_select
|
139
|
+
@channel2.on_ack do |basic_ack|
|
140
|
+
events << :basic_ack
|
141
|
+
end
|
142
|
+
exchange.on_return do |basic_return, metadata, payload|
|
143
|
+
events << :basic_return
|
144
|
+
end
|
145
|
+
|
146
|
+
EventMachine.add_timer(0.5) do
|
147
|
+
exchange.publish("Hi", :persistent => false, :mandatory => true)
|
148
|
+
end
|
149
|
+
|
150
|
+
done(2.0) { events.should == [:basic_return, :basic_ack] }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
context "and CAN NOT be delivered immediately" do
|
157
|
+
it "are delivered immediately after basic.return" do
|
158
|
+
events = Array.new
|
159
|
+
|
160
|
+
queue = @channel1.queue("", :auto_delete => true)
|
161
|
+
exchange = @channel2.fanout("amqpgem.tests.fanout4", :auto_delete => true)
|
162
|
+
|
163
|
+
@channel2.confirm_select
|
164
|
+
@channel2.on_ack do |basic_ack|
|
165
|
+
events << :basic_ack
|
166
|
+
end
|
167
|
+
exchange.on_return do |basic_return, metadata, payload|
|
168
|
+
events << :basic_return
|
169
|
+
end
|
170
|
+
|
171
|
+
EventMachine.add_timer(0.5) do
|
172
|
+
exchange.publish("Hi", :persistent => false, :mandatory => true)
|
173
|
+
end
|
174
|
+
|
175
|
+
done(2.0) { events.should == [:basic_return, :basic_ack] }
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# encoding: utf-8
|
2
|
+
|
2
3
|
require "spec_helper"
|
3
4
|
|
4
5
|
describe "Workload distribution" do
|
@@ -14,7 +15,7 @@ describe "Workload distribution" do
|
|
14
15
|
em_after { AMQP.cleanup_state }
|
15
16
|
|
16
17
|
default_options AMQP_OPTS
|
17
|
-
default_timeout
|
18
|
+
default_timeout 6
|
18
19
|
|
19
20
|
amqp_before do
|
20
21
|
@channel = AMQP::Channel.new
|
@@ -88,7 +89,7 @@ describe "Workload distribution" do
|
|
88
89
|
end
|
89
90
|
|
90
91
|
# for Rubinius, it is surprisingly slow on this workload
|
91
|
-
done(
|
92
|
+
done(3.5) {
|
92
93
|
[@queue1, @queue2, @queue3].each do |q|
|
93
94
|
@received_messages[q.name].size.should == @expected_number_of_messages[q.name]
|
94
95
|
|
@@ -111,7 +112,7 @@ describe "Workload distribution" do
|
|
111
112
|
end
|
112
113
|
|
113
114
|
# 6 seconds are for Rubinius, it is surprisingly slow on this workload
|
114
|
-
done(
|
115
|
+
done(3.5) {
|
115
116
|
[@queue1, @queue2, @queue3].each do |q|
|
116
117
|
@received_messages[q.name].size.should == @expected_number_of_messages[q.name]
|
117
118
|
|
@@ -134,7 +135,7 @@ describe "Workload distribution" do
|
|
134
135
|
end
|
135
136
|
|
136
137
|
# 6 seconds are for Rubinius, it is surprisingly slow on this workload
|
137
|
-
done(
|
138
|
+
done(3.5) {
|
138
139
|
[@queue1, @queue2, @queue3].each do |q|
|
139
140
|
@received_messages[q.name].size.should == @expected_number_of_messages[q.name]
|
140
141
|
|
@@ -157,7 +158,7 @@ describe "Workload distribution" do
|
|
157
158
|
end
|
158
159
|
|
159
160
|
# 6 seconds are for Rubinius, it is surprisingly slow on this workload
|
160
|
-
done(
|
161
|
+
done(3.5) {
|
161
162
|
[@queue1, @queue2, @queue3].each do |q|
|
162
163
|
@received_messages[q.name].size.should == @expected_number_of_messages[q.name]
|
163
164
|
|
@@ -179,7 +180,7 @@ describe "Workload distribution" do
|
|
179
180
|
end
|
180
181
|
|
181
182
|
# 6 seconds are for Rubinius, it is surprisingly slow on this workload
|
182
|
-
done(
|
183
|
+
done(3.5) {
|
183
184
|
[@queue1, @queue2, @queue3].each do |q|
|
184
185
|
@received_messages[q.name].size.should == @expected_number_of_messages[q.name]
|
185
186
|
|
@@ -208,7 +209,7 @@ describe "Workload distribution" do
|
|
208
209
|
end
|
209
210
|
|
210
211
|
# 6 seconds are for Rubinius, it is surprisingly slow on this workload
|
211
|
-
done(
|
212
|
+
done(3.5) {
|
212
213
|
[@queue1, @queue2, @queue3].each do |q|
|
213
214
|
@received_messages[q.name].size.should == @expected_number_of_messages[q.name]
|
214
215
|
|
@@ -230,7 +231,7 @@ describe "Workload distribution" do
|
|
230
231
|
end
|
231
232
|
|
232
233
|
# 6 seconds are for Rubinius, it is surprisingly slow on this workload
|
233
|
-
done(
|
234
|
+
done(3.5) {
|
234
235
|
[@queue1, @queue2, @queue3].each do |q|
|
235
236
|
@received_messages[q.name].size.should == @expected_number_of_messages[q.name]
|
236
237
|
|
@@ -0,0 +1,269 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe "Headers exchange" do
|
6
|
+
|
7
|
+
#
|
8
|
+
# Environment
|
9
|
+
#
|
10
|
+
|
11
|
+
include EventedSpec::AMQPSpec
|
12
|
+
|
13
|
+
default_timeout 5
|
14
|
+
|
15
|
+
amqp_before do
|
16
|
+
@connection = AMQP.connect
|
17
|
+
@channel = AMQP::Channel.new(@connection)
|
18
|
+
|
19
|
+
@channel.on_error do |ch, channel_close|
|
20
|
+
fail "A channel-level exception: #{channel_close.inspect}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
after(:all) do
|
25
|
+
AMQP.cleanup_state
|
26
|
+
done
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
#
|
31
|
+
# Examples
|
32
|
+
#
|
33
|
+
|
34
|
+
# it would be following good practices to split this into
|
35
|
+
# 2 separate examples but I think this particular example
|
36
|
+
# is complete because it demonstrates routing in cases when
|
37
|
+
# different queues are bound with x-match = any AND x-match = all. MK.
|
38
|
+
it "can route messages based on any or all of N headers" do
|
39
|
+
exchange = @channel.headers("amq.match", :durable => true)
|
40
|
+
|
41
|
+
linux_and_ia64_messages = []
|
42
|
+
@channel.queue("", :auto_delete => true).bind(exchange, :arguments => { 'x-match' => 'all', :arch => "IA64", :os => 'linux' }).subscribe do |metadata, payload|
|
43
|
+
linux_and_ia64_messages << [metadata, payload]
|
44
|
+
end
|
45
|
+
|
46
|
+
linux_and_x86_messages = []
|
47
|
+
@channel.queue("", :auto_delete => true).bind(exchange, :arguments => { 'x-match' => 'all', :arch => "x86", :os => 'linux' }).subscribe do |metadata, payload|
|
48
|
+
linux_and_x86_messages << [metadata, payload]
|
49
|
+
end
|
50
|
+
|
51
|
+
any_linux_messages = []
|
52
|
+
@channel.queue("", :auto_delete => true).bind(exchange, :arguments => { :os => 'linux' }).subscribe do |metadata, payload|
|
53
|
+
any_linux_messages << [metadata, payload]
|
54
|
+
end
|
55
|
+
|
56
|
+
osx_or_octocore_messages = []
|
57
|
+
@channel.queue("", :auto_delete => true).bind(exchange, :arguments => { 'x-match' => 'any', :os => 'macosx', :cores => 8 }).subscribe do |metadata, payload|
|
58
|
+
osx_or_octocore_messages << [metadata, payload]
|
59
|
+
end
|
60
|
+
|
61
|
+
riak_messages = []
|
62
|
+
@channel.queue("", :auto_delete => true).bind(exchange, :arguments => { :package => { :name => 'riak', :version => '0.14.2' } }).subscribe do |metadata, payload|
|
63
|
+
riak_messages << [metadata, payload]
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
EventMachine.add_timer(0.5) do
|
68
|
+
exchange.publish "For linux/IA64", :headers => { :arch => "IA64", :os => 'linux' }
|
69
|
+
exchange.publish "For linux/x86", :headers => { :arch => "x86", :os => 'linux' }
|
70
|
+
exchange.publish "For any linux", :headers => { :os => 'linux' }
|
71
|
+
exchange.publish "For OS X", :headers => { :os => 'macosx' }
|
72
|
+
exchange.publish "For solaris/IA64", :headers => { :os => 'solaris', :arch => 'IA64' }
|
73
|
+
exchange.publish "For ocotocore", :headers => { :cores => 8 }
|
74
|
+
|
75
|
+
exchange.publish "For nodes with Riak 0.14.2", :headers => { :package => { :name => 'riak', :version => '0.14.2' } }
|
76
|
+
end
|
77
|
+
|
78
|
+
done(4.5) {
|
79
|
+
linux_and_ia64_messages.size.should == 1
|
80
|
+
linux_and_x86_messages.size.should == 1
|
81
|
+
any_linux_messages.size.should == 3
|
82
|
+
osx_or_octocore_messages.size.should == 2
|
83
|
+
|
84
|
+
riak_messages.size.should == 1
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
describe "Multiple consumers" do
|
94
|
+
include EventedSpec::AMQPSpec
|
95
|
+
default_options AMQP_OPTS
|
96
|
+
default_timeout 5
|
97
|
+
|
98
|
+
describe "bound to a queue with the same single header" do
|
99
|
+
|
100
|
+
#
|
101
|
+
# Environment
|
102
|
+
#
|
103
|
+
|
104
|
+
amqp_before do
|
105
|
+
@channel = AMQP::Channel.new
|
106
|
+
@channel.on_error do |ch, close|
|
107
|
+
raise "Channel-level error!: #{close.inspect}"
|
108
|
+
end
|
109
|
+
|
110
|
+
@queue = @channel.queue("", :auto_delete => true)
|
111
|
+
@exchange = @channel.headers("amqpgem.tests.integration.headers.exchange1", :auto_delete => true)
|
112
|
+
|
113
|
+
@queue.bind(@exchange, :arguments => { :slug => "all" })
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
it "get messages distributed to them in a round-robin manner" do
|
119
|
+
mailbox1 = Array.new
|
120
|
+
mailbox2 = Array.new
|
121
|
+
|
122
|
+
consumer1 = AMQP::Consumer.new(@channel, @queue).consume.on_delivery { |metadata, payload| mailbox1 << payload }
|
123
|
+
consumer2 = AMQP::Consumer.new(@channel, @queue).consume.on_delivery { |metadata, payload| mailbox2 << payload }
|
124
|
+
|
125
|
+
|
126
|
+
EventMachine.add_timer(0.5) do
|
127
|
+
12.times { @exchange.publish(".", :headers => { :slug => "all" }) }
|
128
|
+
12.times { @exchange.publish(".", :headers => { :slug => "rspec" }) }
|
129
|
+
end
|
130
|
+
|
131
|
+
done(3.5) {
|
132
|
+
mailbox1.size.should == 6
|
133
|
+
mailbox2.size.should == 6
|
134
|
+
}
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
describe "bound to a queue with the same two header & x-match = all" do
|
141
|
+
|
142
|
+
#
|
143
|
+
# Environment
|
144
|
+
#
|
145
|
+
|
146
|
+
amqp_before do
|
147
|
+
@channel = AMQP::Channel.new
|
148
|
+
@channel.on_error do |ch, close|
|
149
|
+
raise "Channel-level error!: #{close.inspect}"
|
150
|
+
end
|
151
|
+
|
152
|
+
@queue = @channel.queue("", :auto_delete => true)
|
153
|
+
@exchange = @channel.headers("amqpgem.tests.integration.headers.exchange1", :auto_delete => true)
|
154
|
+
|
155
|
+
@queue.bind(@exchange, :arguments => { :slug => "all", :arch => "ia64", 'x-match' => 'all' })
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
it "get messages distributed to them in a round-robin manner" do
|
160
|
+
mailbox1 = Array.new
|
161
|
+
mailbox2 = Array.new
|
162
|
+
|
163
|
+
consumer1 = AMQP::Consumer.new(@channel, @queue).consume.on_delivery { |metadata, payload| mailbox1 << payload }
|
164
|
+
consumer2 = AMQP::Consumer.new(@channel, @queue).consume.on_delivery { |metadata, payload| mailbox2 << payload }
|
165
|
+
|
166
|
+
EventMachine.add_timer(0.5) do
|
167
|
+
12.times { @exchange.publish(".", :headers => { :slug => "all", :arch => "ia64" }) }
|
168
|
+
12.times { @exchange.publish(".", :headers => { :slug => "rspec", :arch => "ia64" }) }
|
169
|
+
end
|
170
|
+
|
171
|
+
done(3.5) {
|
172
|
+
mailbox1.size.should == 6
|
173
|
+
mailbox2.size.should == 6
|
174
|
+
}
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
describe "bound to 2 queues with the same two header & x-match = all" do
|
181
|
+
|
182
|
+
#
|
183
|
+
# Environment
|
184
|
+
#
|
185
|
+
|
186
|
+
amqp_before do
|
187
|
+
@channel = AMQP::Channel.new
|
188
|
+
@channel.on_error do |ch, close|
|
189
|
+
raise "Channel-level error!: #{close.inspect}"
|
190
|
+
end
|
191
|
+
|
192
|
+
@queue1 = @channel.queue("", :auto_delete => true)
|
193
|
+
@queue2 = @channel.queue("", :auto_delete => true)
|
194
|
+
@exchange = @channel.headers("amqpgem.tests.integration.headers.exchange1", :auto_delete => true)
|
195
|
+
|
196
|
+
args = { :slug => "all", :arch => "ia64", 'x-match' => 'all' }
|
197
|
+
@queue1.bind(@exchange, :arguments => args)
|
198
|
+
@queue2.bind(@exchange, :arguments => args)
|
199
|
+
end
|
200
|
+
|
201
|
+
it "get messages distributed to both queues, and in a round-robin manner between consumers on one queue" do
|
202
|
+
mailbox1 = Array.new
|
203
|
+
mailbox2 = Array.new
|
204
|
+
mailbox3 = Array.new
|
205
|
+
mailbox4 = Array.new
|
206
|
+
|
207
|
+
consumer1 = AMQP::Consumer.new(@channel, @queue1).consume.on_delivery { |metadata, payload| mailbox1 << payload }
|
208
|
+
consumer2 = AMQP::Consumer.new(@channel, @queue1).consume.on_delivery { |metadata, payload| mailbox2 << payload }
|
209
|
+
consumer3 = AMQP::Consumer.new(@channel, @queue2).consume.on_delivery { |metadata, payload| mailbox3 << payload }
|
210
|
+
consumer4 = AMQP::Consumer.new(@channel, @queue2).consume.on_delivery { |metadata, payload| mailbox4 << payload }
|
211
|
+
|
212
|
+
EventMachine.add_timer(0.5) do
|
213
|
+
12.times { |i| @exchange.publish("all-#{i}", :headers => { :slug => "all", :arch => "ia64" }) }
|
214
|
+
16.times { |i| @exchange.publish("rspec-#{i}", :headers => { :slug => "rspec", :arch => "ia64" }) }
|
215
|
+
end
|
216
|
+
|
217
|
+
done(3.5) {
|
218
|
+
mailbox1.size.should == 6
|
219
|
+
mailbox1.should == ["all-0", "all-2", "all-4", "all-6", "all-8", "all-10"]
|
220
|
+
|
221
|
+
mailbox2.size.should == 6
|
222
|
+
mailbox2.should == ["all-1", "all-3", "all-5", "all-7", "all-9", "all-11"]
|
223
|
+
|
224
|
+
mailbox3.size.should == 6
|
225
|
+
mailbox4.size.should == 6
|
226
|
+
}
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
|
232
|
+
|
233
|
+
describe "bound to a queue with the same two header & x-match = any" do
|
234
|
+
|
235
|
+
#
|
236
|
+
# Environment
|
237
|
+
#
|
238
|
+
|
239
|
+
amqp_before do
|
240
|
+
@channel = AMQP::Channel.new
|
241
|
+
@channel.on_error do |ch, close|
|
242
|
+
raise "Channel-level error!: #{close.inspect}"
|
243
|
+
end
|
244
|
+
|
245
|
+
@queue = @channel.queue("", :auto_delete => true)
|
246
|
+
@exchange = @channel.headers("amqpgem.tests.integration.headers.exchange1", :auto_delete => true)
|
247
|
+
|
248
|
+
@queue.bind(@exchange, :arguments => { :slug => "all", :arch => "ia64", 'x-match' => 'any' })
|
249
|
+
end
|
250
|
+
|
251
|
+
it "get messages distributed to them in a round-robin manner" do
|
252
|
+
mailbox1 = Array.new
|
253
|
+
mailbox2 = Array.new
|
254
|
+
|
255
|
+
consumer1 = AMQP::Consumer.new(@channel, @queue).consume.on_delivery { |metadata, payload| mailbox1 << payload }
|
256
|
+
consumer2 = AMQP::Consumer.new(@channel, @queue).consume.on_delivery { |metadata, payload| mailbox2 << payload }
|
257
|
+
|
258
|
+
EventMachine.add_timer(0.5) do
|
259
|
+
12.times { @exchange.publish(".", :headers => { :slug => "all", :arch => "ia64" }) }
|
260
|
+
4.times { @exchange.publish(".", :headers => { :slug => "rspec", :arch => "ia64" }) }
|
261
|
+
end
|
262
|
+
|
263
|
+
done(3.5) {
|
264
|
+
mailbox1.size.should == 8
|
265
|
+
mailbox2.size.should == 8
|
266
|
+
}
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|