amqp 0.8.0.rc12 → 0.8.0.rc13
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -1
- data/.yardopts +2 -1
- data/CONTRIBUTORS +29 -22
- data/Gemfile +2 -1
- data/README.md +241 -0
- data/amqp.gemspec +7 -5
- data/bin/set_test_suite_realms_up.sh +6 -6
- data/docs/08Migration.textile +3 -1
- data/docs/Bindings.textile +3 -1
- data/docs/Clustering.textile +4 -0
- data/docs/ConnectingToTheBroker.textile +108 -86
- data/docs/ConnectionEncryptionWithTLS.textile +3 -1
- data/docs/DocumentationGuidesIndex.textile +24 -2
- data/docs/Durability.textile +22 -1
- data/docs/ErrorHandling.textile +21 -1
- data/docs/Exchanges.textile +181 -9
- data/docs/GettingStarted.textile +65 -167
- data/docs/Queues.textile +400 -355
- data/docs/RabbitMQVersions.textile +34 -3
- data/docs/Routing.textile +4 -1
- data/docs/RunningTests.textile +116 -0
- data/docs/Troubleshooting.textile +131 -0
- data/docs/VendorSpecificExtensions.textile +20 -0
- data/examples/channels/qos_aka_prefetch.rb +3 -3
- data/examples/channels/qos_aka_prefetch_without_callback.rb +2 -2
- data/examples/error_handling/channel_level_exception.rb +1 -1
- data/examples/error_handling/channel_level_exception_with_multiple_channels_involved.rb +1 -0
- data/examples/error_handling/connection_level_exception.rb +26 -0
- data/examples/error_handling/global_channel_level_exception_handler.rb +3 -3
- data/examples/exchanges/autodeletion_of_exchanges.rb +37 -0
- data/examples/extensions/rabbitmq/per_queue_message_ttl.rb +3 -3
- data/examples/extensions/rabbitmq/publisher_confirmations_with_transient_messages.rb +2 -2
- data/examples/guides/getting_started/{03_babblr.rb → 03_blabbr.rb} +0 -0
- data/examples/guides/queues/01a_declaring_a_server_named_queue_using_queue_constructor.rb +18 -0
- data/examples/guides/queues/01b_declaring_a_queue_using_queue_constructor.rb +18 -0
- data/examples/guides/queues/02a_declaring_a_durable_shared_queue.rb +18 -0
- data/examples/guides/queues/02b_declaring_a_durable_shared_queue.rb +18 -0
- data/examples/guides/queues/03a_declaring_a_temporary_exclusive_queue.rb +19 -0
- data/examples/guides/queues/03b_declaring_a_temporary_exclusive_queue.rb +18 -0
- data/examples/guides/queues/{05_binding_a_queue_using_exchange_instance.rb → 04_bind_a_queue_using_exchange_instance.rb} +2 -2
- data/examples/guides/queues/{06_biding_a_queue_using_exchange_name_string.rb → 05_bind_a_queue_using_exchange_name.rb} +2 -2
- data/examples/guides/queues/{07_subscribing_to_receive_messages.rb → 06_subscribe_to_receive_messages.rb} +1 -1
- data/examples/guides/queues/{08_poll_for_messages.rb → 07_fetch_a_message_from_the_queue.rb} +1 -1
- data/examples/guides/queues/{09_unsubscribing_a_consumer.rb → 08_unsubscribing_a_consumer.rb} +0 -0
- data/examples/guides/queues/{10_unbinding_from_exchange.rb → 09_unbinding_from_exchange.rb} +2 -2
- data/examples/guides/queues/{11_purge_a_queue.rb → 10_purge_a_queue.rb} +2 -2
- data/examples/guides/queues/{12_deleting_a_queue.rb → 11_deleting_a_queue.rb} +2 -2
- data/examples/hello_world.rb +1 -1
- data/examples/hello_world_with_an_empty_string.rb +33 -0
- data/examples/issues/amq_client_issue_7.rb +31 -0
- data/examples/issues/amq_protocol_issue_14.rb +46 -0
- data/examples/issues/issue_75.rb +23 -0
- data/examples/issues/issue_79.rb +35 -0
- data/examples/issues/issue_80.rb +40 -0
- data/examples/publishing/{publishing_and_immediately_stopping_event_loop.rb → publishing_a_one_off_message.rb} +9 -12
- data/examples/publishing/publishing_callback.rb +52 -0
- data/examples/publishing/returned_messages.rb +3 -3
- data/examples/queues/accessing_message_metadata.rb +60 -0
- data/examples/queues/queue_status.rb +0 -7
- data/examples/queues/rejecting_messages_without_requeueuing.rb +47 -0
- data/examples/queues/using_explicit_acknowledgements.rb +96 -0
- data/examples/routing/headers_routing.rb +54 -0
- data/lib/amqp/channel.rb +245 -40
- data/lib/amqp/client.rb +23 -11
- data/lib/amqp/exchange.rb +58 -41
- data/lib/amqp/queue.rb +66 -13
- data/lib/amqp/version.rb +1 -1
- data/spec/integration/authentication_spec.rb +5 -5
- data/spec/integration/basic_get_spec.rb +1 -1
- data/spec/integration/channel_close_spec.rb +10 -3
- data/spec/integration/queue_declaration_spec.rb +26 -5
- data/spec/integration/topic_subscription_spec.rb +1 -1
- data/spec/unit/amqp/client_spec.rb +7 -54
- data/tasks.rb +1 -8
- metadata +64 -23
- data/README.textile +0 -229
@@ -1,20 +1,24 @@
|
|
1
|
+
# @title Ruby AMQP gem documentation guides
|
2
|
+
|
1
3
|
h1. Ruby AMQP gem documentation guides
|
2
4
|
|
3
5
|
h2. Guide list
|
4
6
|
|
5
7
|
* {file:docs/GettingStarted.textile Getting started}
|
6
8
|
* {file:docs/ConnectingToTheBroker.textile Connecting to the broker}
|
7
|
-
* {file:docs/Queues.textile
|
8
|
-
* {file:docs/Exchanges.textile
|
9
|
+
* {file:docs/Queues.textile Working with queues}
|
10
|
+
* {file:docs/Exchanges.textile Working with exchanges}
|
9
11
|
* {file:docs/Bindings.textile Bindings}
|
10
12
|
* {file:docs/Routing.textile Routing}
|
11
13
|
* {file:docs/Durability.textile Durability and message persistence}
|
12
14
|
* {file:docs/ErrorHandling.textile Error handling}
|
13
15
|
* {file:docs/08Migration.textile Upgrading from version 0.6.x/0.7.x to 0.8.x and above}
|
16
|
+
* {file:docs/Troubleshooting.textile Troubleshooting and debugging AMQP applications}
|
14
17
|
* {file:docs/Clustering.textile Clustering}
|
15
18
|
* {file:docs/RabbitMQVersions.textile RabbitMQ versions}
|
16
19
|
* {file:docs/ConnectionEncryptionWithTLS.textile Using TLS (SSL)}
|
17
20
|
* {file:docs/VendorSpecificExtensions.textile Vendor-specific extensions to AMQP 0.9.1 spec}
|
21
|
+
* {file:docs/RunningTests.textile Running amqp gem test suite}
|
18
22
|
|
19
23
|
|
20
24
|
h2. Tell us what you think!
|
@@ -24,3 +28,21 @@ what was unclear? what wasn't covered? maybe you don't like guide style or gramm
|
|
24
28
|
key to making documentation better.
|
25
29
|
|
26
30
|
If mailing list communication is not an option for you for some reason, you can "contact guides author directly":mailto:michael@novemberain.com?subject=amqp%20gem%20documentation
|
31
|
+
|
32
|
+
|
33
|
+
<div id="disqus_thread"></div>
|
34
|
+
<script type="text/javascript">
|
35
|
+
/* * * CONFIGURATION VARIABLES * * */
|
36
|
+
var disqus_shortname = 'rubyamqpdocs'; // required: replace example with your forum shortname
|
37
|
+
|
38
|
+
var disqus_developer = 0; // set to 1 on local machine for testing comments
|
39
|
+
var disqus_identifier = 'amqp_documentation_guides_index';
|
40
|
+
var disqus_url = 'http://rdoc.info/github/ruby-amqp/amqp/master/file/docs/DocumentationGuidesIndex.textile';
|
41
|
+
|
42
|
+
/* * * DON'T EDIT BELOW THIS LINE * * */
|
43
|
+
(function() {
|
44
|
+
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
45
|
+
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
|
46
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
47
|
+
})();
|
48
|
+
</script>
|
data/docs/Durability.textile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# @title Ruby AMQP gem: Durability and related matters
|
2
|
+
|
1
3
|
h1. Durability and related matters
|
2
4
|
|
3
5
|
|
@@ -9,7 +11,7 @@ topics related to durability, for example, durability in cluster environment.
|
|
9
11
|
|
10
12
|
h2. Covered versions
|
11
13
|
|
12
|
-
This guide covers amqp gem v0.8.0 and later.
|
14
|
+
This guide covers "Ruby amqp gem":http://github.com/ruby-amqp/amqp v0.8.0 and later.
|
13
15
|
|
14
16
|
|
15
17
|
h2. Entity durability and message persistence
|
@@ -101,3 +103,22 @@ what was unclear? what wasn't covered? maybe you don't like guide style or gramm
|
|
101
103
|
key to making documentation better.
|
102
104
|
|
103
105
|
If mailing list communication is not an option for you for some reason, you can "contact guides author directly":mailto:michael@novemberain.com?subject=amqp%20gem%20documentation
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
<div id="disqus_thread"></div>
|
110
|
+
<script type="text/javascript">
|
111
|
+
/* * * CONFIGURATION VARIABLES * * */
|
112
|
+
var disqus_shortname = 'rubyamqpdocs'; // required: replace example with your forum shortname
|
113
|
+
|
114
|
+
var disqus_developer = 0; // set to 1 on local machine for testing comments
|
115
|
+
var disqus_identifier = 'amqp_durability';
|
116
|
+
var disqus_url = 'http://rdoc.info/github/ruby-amqp/amqp/master/file/docs/Durability.textile';
|
117
|
+
|
118
|
+
/* * * DON'T EDIT BELOW THIS LINE * * */
|
119
|
+
(function() {
|
120
|
+
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
121
|
+
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
|
122
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
123
|
+
})();
|
124
|
+
</script>
|
data/docs/ErrorHandling.textile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# @title Ruby AMQP gem: Error handling and recovery
|
2
|
+
|
1
3
|
h1. Error handling and recovery
|
2
4
|
|
3
5
|
h2. About this guide
|
@@ -17,7 +19,7 @@ issues like
|
|
17
19
|
|
18
20
|
h2. Covered versions
|
19
21
|
|
20
|
-
This guide covers amqp gem v0.8.0 and later.
|
22
|
+
This guide covers "Ruby amqp gem":http://github.com/ruby-amqp/amqp v0.8.0 and later.
|
21
23
|
|
22
24
|
|
23
25
|
h2. Code examples
|
@@ -233,3 +235,21 @@ what was unclear? what wasn't covered? maybe you don't like guide style or gramm
|
|
233
235
|
key to making documentation better.
|
234
236
|
|
235
237
|
If mailing list communication is not an option for you for some reason, you can "contact guides author directly":mailto:michael@novemberain.com?subject=amqp%20gem%20documentation
|
238
|
+
|
239
|
+
|
240
|
+
<div id="disqus_thread"></div>
|
241
|
+
<script type="text/javascript">
|
242
|
+
/* * * CONFIGURATION VARIABLES * * */
|
243
|
+
var disqus_shortname = 'rubyamqpdocs'; // required: replace example with your forum shortname
|
244
|
+
|
245
|
+
var disqus_developer = 0; // set to 1 on local machine for testing comments
|
246
|
+
var disqus_identifier = 'amqp_error_handling';
|
247
|
+
var disqus_url = 'http://rdoc.info/github/ruby-amqp/amqp/master/file/docs/ErrorHandling.textile';
|
248
|
+
|
249
|
+
/* * * DON'T EDIT BELOW THIS LINE * * */
|
250
|
+
(function() {
|
251
|
+
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
252
|
+
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
|
253
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
254
|
+
})();
|
255
|
+
</script>
|
data/docs/Exchanges.textile
CHANGED
@@ -1,44 +1,193 @@
|
|
1
|
-
|
1
|
+
# @title Ruby AMQP gem: Working with exchanges
|
2
|
+
|
3
|
+
h1. Working with exchanges
|
2
4
|
|
3
5
|
|
4
6
|
h2. About this guide
|
5
7
|
|
6
|
-
|
8
|
+
This guide covers everything related to exchanges in AMQP 0.9.1, common usage scenarios and how to accomplish typical operations using
|
9
|
+
amqp gem.
|
7
10
|
|
8
11
|
|
9
12
|
h2. Covered versions
|
10
13
|
|
11
|
-
This guide covers amqp gem v0.8.0 and later.
|
14
|
+
This guide covers "Ruby amqp gem":http://github.com/ruby-amqp/amqp v0.8.0 and later.
|
12
15
|
|
13
16
|
|
14
17
|
h2. Exchanges in AMQP 0.9.1, briefly
|
15
18
|
|
16
|
-
|
19
|
+
h3. What are AMQP exchanges?
|
20
|
+
|
21
|
+
An exchange accepts messages from a producer application and routes these to message queues. They can be thought of as "mailboxes" of AMQP
|
22
|
+
world. Unlike some other messaging middleware products and protocols, in AMQP messages are *not* published directly to queues: they
|
23
|
+
are published to exchanges that route them to queue(s) using pre-arranged criteria (called bindings).
|
24
|
+
|
25
|
+
There are multiple exchange types in AMQP 0.9.1, each with its own routing semantics. Custom exchange types can be created to cover
|
26
|
+
sophisticated routing scenarios (for example, routing based on geolocation data), edge cases or just for convenience.
|
27
|
+
|
28
|
+
|
29
|
+
h3. Concept of bindings
|
30
|
+
|
31
|
+
Binding is an association between a queue and an exchange. Queues must be bound to at least one exchange in order to receive messages from publishers.
|
32
|
+
Learn more about bindings in {file:docs/Bindings.textile Bindings guide}.
|
33
|
+
|
34
|
+
|
35
|
+
h3. Attributes
|
36
|
+
|
37
|
+
Exchanges have several attributes associated with them:
|
38
|
+
|
39
|
+
* Name
|
40
|
+
* Type (direct, fanout, topic, headers or some custom type)
|
41
|
+
* Durability
|
42
|
+
* Whether exchange is auto-deleted when no longer used
|
43
|
+
* Other metadata (aka X-arguments)
|
17
44
|
|
18
45
|
|
19
46
|
h2. Exchange types
|
20
47
|
|
21
|
-
|
48
|
+
There are 4 built-in exchange types in AMQP 0.9.1:
|
49
|
+
|
50
|
+
* Direct
|
51
|
+
* Fanout
|
52
|
+
* Topic
|
53
|
+
* Headers
|
54
|
+
|
55
|
+
As stated previously, each exchange type has own routing semantics and new exchange types can be added by extending brokers with plugins.
|
56
|
+
Custom exchange types begin with x-, much like custom HTTP headers, for example, "x-recent-history exchange":https://github.com/videlalvaro/rabbitmq-recent-history-exchange.
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
h2. Message attributes
|
62
|
+
|
63
|
+
Before we start looking at various exchange types and their routing semantics, we need to introduce idea of message attributes.
|
64
|
+
Every AMQP message has a number of *attributes*. Some attributes are important and used very often, other are used rarely. AMQP message attributes are metadata:
|
65
|
+
they are similar in purpose to HTTP request and response headers.
|
66
|
+
|
67
|
+
Every AMQP 0.9.1 message has an attribute called the *routing key*. The routing key is an "address" that the exchange may use to decide how to route
|
68
|
+
the message (similar to, but more generic, than URL in HTTP). Most exchange types use routing key to implement routing logic, but some ignore
|
69
|
+
it and use other criteria (for example, message content).
|
70
|
+
|
71
|
+
|
22
72
|
|
23
73
|
|
24
74
|
h2. Fanout exchanges
|
25
75
|
|
26
|
-
|
76
|
+
Fanout exchanges route messages to all queues bound to it, the routing key is ignored. If N queues are bound to a fanout exchange,
|
77
|
+
when a new message is published to that exchange, a *copy of the message* is delivered to all N queues, so fanout exchanges
|
78
|
+
are ideal for "broadcast routing":http://en.wikipedia.org/wiki/Broadcasting_%28computing%29 of messages.
|
79
|
+
|
80
|
+
Graphically this can be represented as
|
81
|
+
|
82
|
+
!http://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Broadcast.svg/500px-Broadcast.svg.png!
|
83
|
+
|
84
|
+
AMQP 0.9.1 brokers must implement fanout exchange type and pre-declare one instance with the name of "amq.fanout".
|
85
|
+
This means that applications can rely on that exchange to always be available to them. Each vhost has a separate instance of that exchange,
|
86
|
+
it is *not shared across vhosts* for obvious reasons.
|
87
|
+
|
27
88
|
|
28
89
|
|
29
90
|
h2. Direct exchanges
|
30
91
|
|
31
|
-
|
92
|
+
Direct exchange delivers messages to queues based on *message routing key*, an attribute every AMQP 0.9.1 message has.
|
93
|
+
|
94
|
+
Here is how it works:
|
95
|
+
|
96
|
+
* A queue binds to the exchange with a routing key, K.
|
97
|
+
* When a new message with routing key R arrives to direct exchange, the exchange routes it to the queue if K = R.
|
98
|
+
|
99
|
+
Direct exchange is ideal for "unicast routing":http://en.wikipedia.org/wiki/Unicast of messages (although it can be used for "multicast routing":http://en.wikipedia.org/wiki/Multicast, too).
|
100
|
+
|
101
|
+
!http://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Unicast.svg/500px-Unicast.svg.png!
|
102
|
+
|
103
|
+
AMQP 0.9.1 brokers must implement direct exchange type and pre-declare two instances
|
104
|
+
|
105
|
+
* *amq.direct*.
|
106
|
+
* *""* (unnamed, referred to as an empty string by many clients including amqp Ruby gem) exchange known as *default exchange*.
|
107
|
+
|
108
|
+
This means that applications can rely on those exchanges to always be available to them. Each vhost has separate instances of those exchanges,
|
109
|
+
they are *not shared across vhosts* for obvious reasons.
|
110
|
+
|
111
|
+
|
112
|
+
h3. Default exchange
|
113
|
+
|
114
|
+
Default exchange is a direct exchange with no name (amqp gem refers to it using an empty string) pre-declared by the broker. It has one key special
|
115
|
+
property that makes it very useful for simple applications: *every queue is automatically bound to it with a routing key the same as queue name".
|
116
|
+
|
117
|
+
For example, when you declare a queue with the name of "search.indexing.online", AMQP broker will bind it to the default exchange using
|
118
|
+
"search.indexing.online" as routing key. So a message publishes to the default exchange with routing key = "search.indexing.online"
|
119
|
+
will be routed to the queue "search.indexing.online". In other words, default exchange makes it possible to "deliver messages directly to queues",
|
120
|
+
even though that is not technically correct.
|
121
|
+
|
122
|
+
|
123
|
+
amqp gem offers two ways of obtaining of the default exchange: {AMQP::Channel#default_exchange} and {AMQP::Channel#direct} (use empty string as exchange name).
|
124
|
+
{AMQP::Exchange#initialize} can be used as well but requires more effort and for this particular case offers no benefits over instance methods on {AMQP::Channel}.
|
125
|
+
|
126
|
+
The default exchange is what the "Hello, World" example uses:
|
127
|
+
|
128
|
+
{include:file:examples/hello_world.rb}
|
129
|
+
|
32
130
|
|
33
131
|
|
34
132
|
h2. Topic exchanges
|
35
133
|
|
134
|
+
Topic exchanges route messages to one or many queues based on matching between message routing key and pattern that was used for binding
|
135
|
+
queue to the exchange.
|
136
|
+
|
137
|
+
|
138
|
+
Topic exchanges are commonly used for "multicast routing":http://en.wikipedia.org/wiki/Multicast of messages.
|
139
|
+
|
140
|
+
!http://upload.wikimedia.org/wikipedia/commons/thumb/3/30/Multicast.svg/500px-Multicast.svg.png!
|
141
|
+
|
142
|
+
Topic exchanges can be used for "broadcast routing":http://en.wikipedia.org/wiki/Broadcasting_%28computing%29 but usually fanout exchanges are more efficient at that.
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
Here is an example of topic exchange in action:
|
147
|
+
|
148
|
+
{include:file:examples/routing/weather_updates.rb}
|
149
|
+
|
150
|
+
TBD
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
h2. Headers exchanges
|
155
|
+
|
156
|
+
|
157
|
+
|
158
|
+
TBD
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
h2. Custom exchange types
|
163
|
+
|
164
|
+
TBD
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
h2. Declaring/Instantiating exchanges
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
Below is an example of {AMQP::Exchange#initialize} used with a callback:
|
173
|
+
|
174
|
+
{include:file:examples/exchanges/declare_an_exchange_without_assignment.rb}
|
175
|
+
|
176
|
+
|
36
177
|
TBD
|
37
178
|
|
38
179
|
|
39
180
|
|
40
181
|
h2. Publishing messages
|
41
182
|
|
183
|
+
|
184
|
+
h3. Publishing one-off messages
|
185
|
+
|
186
|
+
The following example publishes a message and *safely* closes AMQP connection after that by passing a block
|
187
|
+
to {AMQP::Exchange#publish}:
|
188
|
+
|
189
|
+
{include:file:examples/publishing/publishing_a_one_off_message.rb}
|
190
|
+
|
42
191
|
TBD
|
43
192
|
|
44
193
|
|
@@ -56,13 +205,18 @@ TBD
|
|
56
205
|
|
57
206
|
h2. Deleting exchanges
|
58
207
|
|
208
|
+
|
209
|
+
Exchanges are be *auto-deleted*. An example that uses two auto-deleted exchanges:
|
210
|
+
|
211
|
+
{include:file:examples/exchanges/autodeletion_of_exchanges.rb}
|
212
|
+
|
59
213
|
TBD
|
60
214
|
|
61
215
|
|
62
216
|
|
63
217
|
h2. Exchange durability vs Message durability
|
64
218
|
|
65
|
-
|
219
|
+
See {file:docs/Durability.textile Durability guide}
|
66
220
|
|
67
221
|
|
68
222
|
|
@@ -74,7 +228,7 @@ TBD
|
|
74
228
|
|
75
229
|
h2. Vendor-specific extensions related to exchanges
|
76
230
|
|
77
|
-
|
231
|
+
See {file:docs/VendorSpecificExtensions.textile Vendor-specific Extensions guide}
|
78
232
|
|
79
233
|
|
80
234
|
|
@@ -90,3 +244,21 @@ what was unclear? what wasn't covered? maybe you don't like guide style or gramm
|
|
90
244
|
key to making documentation better.
|
91
245
|
|
92
246
|
If mailing list communication is not an option for you for some reason, you can "contact guides author directly":mailto:michael@novemberain.com?subject=amqp%20gem%20documentation
|
247
|
+
|
248
|
+
|
249
|
+
<div id="disqus_thread"></div>
|
250
|
+
<script type="text/javascript">
|
251
|
+
/* * * CONFIGURATION VARIABLES * * */
|
252
|
+
var disqus_shortname = 'rubyamqpdocs'; // required: replace example with your forum shortname
|
253
|
+
|
254
|
+
var disqus_developer = 0; // set to 1 on local machine for testing comments
|
255
|
+
var disqus_identifier = 'amqp_exchanges';
|
256
|
+
var disqus_url = 'http://rdoc.info/github/ruby-amqp/amqp/master/file/docs/Exchanges.textile';
|
257
|
+
|
258
|
+
/* * * DON'T EDIT BELOW THIS LINE * * */
|
259
|
+
(function() {
|
260
|
+
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
261
|
+
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
|
262
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
263
|
+
})();
|
264
|
+
</script>
|
data/docs/GettingStarted.textile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# @title Ruby AMQP gem: Getting Started with AMQP and Ruby
|
2
|
+
|
1
3
|
h1. Getting started with AMQP Ruby gem
|
2
4
|
|
3
5
|
|
@@ -8,38 +10,46 @@ It should take about 20 minutes to read and study provided code examples. This g
|
|
8
10
|
|
9
11
|
* Installing RabbitMQ, a mature popular implementation of multiple versions of AMQP protocol.
|
10
12
|
* Installing amqp gem via "Rubygems":http://rubygems.org and "Bundler":http://gembundler.com.
|
11
|
-
* Running
|
13
|
+
* Running the "Hello, world" of messaging, a simple demonstration of 1:1 communication.
|
12
14
|
* Creating a "Twitter like" publish/subscribe example with 1 publisher and 4 subscribers, a case of 1:n communication.
|
13
15
|
* Creating a topic routing example with 2 publishers and 8 subscribers, a case of n:m communication when subscribers only receive messages they are interested in.
|
14
16
|
|
15
17
|
|
16
18
|
h2. Covered versions
|
17
19
|
|
18
|
-
This guide covers amqp gem v0.8.0 and later.
|
20
|
+
This guide covers "Ruby amqp gem":http://github.com/ruby-amqp/amqp v0.8.0 and later.
|
19
21
|
|
20
22
|
|
21
23
|
h2. Installing RabbitMQ
|
22
24
|
|
23
|
-
RabbitMQ site has a good "installation guide":http://www.rabbitmq.com/install.html that covers many operating systems.
|
24
|
-
On Mac OS X, the fastest way to install RabbitMQ is with Homebrew:
|
25
|
+
"RabbitMQ site":http://rabbitmq.com has a good "installation guide":http://www.rabbitmq.com/install.html that covers many operating systems.
|
26
|
+
On Mac OS X, the fastest way to install RabbitMQ is with "Homebrew":http://mxcl.github.com/homebrew/:
|
25
27
|
|
28
|
+
<pre>
|
26
29
|
<code>
|
27
30
|
brew install rabbitmq
|
28
31
|
</code>
|
32
|
+
</pre>
|
29
33
|
|
30
34
|
then run it:
|
35
|
+
|
36
|
+
<pre>
|
31
37
|
<code>
|
32
38
|
rabbitmq-server
|
33
39
|
</code>
|
40
|
+
</pre>
|
41
|
+
|
42
|
+
On Debian and Ubuntu, you can either "download RabbitMQ .deb package":http://www.rabbitmq.com/server.html and install it with
|
43
|
+
"dpkg":http://www.debian.org/doc/FAQ/ch-pkgtools.en.html or use "apt repository RabbitMQ team provides":http://www.rabbitmq.com/debian.html#apt.
|
44
|
+
For RPM-based distributions like RedHat or CentOS RabbitMQ team provides an "RPM package":http://www.rabbitmq.com/install.html#rpm.
|
34
45
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
or CentOS RabbitMQ team provides an RPM package.
|
46
|
+
<span class="note">
|
47
|
+
RabbitMQ package in even recent (10.10) versions of Ubuntu are outdated and *won't work with amqp gem 0.8.0 and later* (we need at least version 2.0).
|
48
|
+
</span>
|
39
49
|
|
40
50
|
|
41
51
|
|
42
|
-
h2. Installing amqp gem
|
52
|
+
h2. Installing Ruby amqp gem
|
43
53
|
|
44
54
|
h3. Make sure you have Ruby installed
|
45
55
|
|
@@ -55,17 +65,27 @@ This guides assumes you have one of the supported Ruby implementations installed
|
|
55
65
|
h3. With Rubygems
|
56
66
|
|
57
67
|
To get amqp gem 0.8.0
|
68
|
+
|
69
|
+
h4. On Microsoft Windows 7
|
70
|
+
|
58
71
|
<pre>
|
59
|
-
|
60
|
-
gem install amqp --pre
|
61
|
-
</
|
72
|
+
gem install eventmachine --pre
|
73
|
+
gem install amqp --pre --version "~> 0.8.0.RC12"
|
74
|
+
</pre>
|
75
|
+
|
76
|
+
h4. On other OSes or JRuby:
|
77
|
+
|
78
|
+
<pre>
|
79
|
+
gem install amqp --pre --version "~> 0.8.0.RC12"
|
62
80
|
</pre>
|
63
81
|
|
64
82
|
h3. With Bundler
|
65
83
|
|
66
84
|
<pre>
|
67
85
|
<code>
|
68
|
-
|
86
|
+
source :rubygems
|
87
|
+
|
88
|
+
gem "amqp", "~> 0.8.0.RC12" # optionally: :git => "git://github.com/ruby-amqp/amqp.git", :branch => "master"
|
69
89
|
</code>
|
70
90
|
</pre>
|
71
91
|
|
@@ -80,43 +100,18 @@ irb -rubygems
|
|
80
100
|
:001 > require "amqp"
|
81
101
|
=> true
|
82
102
|
:002 > AMQP::VERSION
|
83
|
-
=> "0.8.0.
|
103
|
+
=> "0.8.0.rc12"
|
84
104
|
</code>
|
85
105
|
</pre>
|
86
106
|
|
87
107
|
|
88
|
-
h2.
|
89
|
-
|
90
|
-
Lets begin with a classic Hello, world example. First, here's the code:
|
91
|
-
|
92
|
-
<pre>
|
93
|
-
<code>
|
94
|
-
#!/usr/bin/env ruby
|
95
|
-
# encoding: utf-8
|
96
|
-
|
97
|
-
require "rubygems"
|
98
|
-
require "amqp"
|
99
|
-
|
100
|
-
EventMachine.run do
|
101
|
-
connection = AMQP.connect(:host => '127.0.0.1')
|
102
|
-
puts "Connected to AMQP broker. Running #{AMQP::VERSION} version of the gem..."
|
108
|
+
h2. "Hello, world" example
|
103
109
|
|
104
|
-
|
105
|
-
queue = channel.queue("amqpgem.examples.hello_world", :auto_delete => true)
|
106
|
-
exchange = channel.direct("")
|
110
|
+
Lets begin with the classic "Hello, world" example. First, here's the code:
|
107
111
|
|
108
|
-
|
109
|
-
puts "Received a message: #{payload}. Disconnecting..."
|
112
|
+
<script src="https://gist.github.com/998690.js"> </script>
|
110
113
|
|
111
|
-
|
112
|
-
EM.stop { exit }
|
113
|
-
}
|
114
|
-
end
|
115
|
-
|
116
|
-
exchange.publish "Hello, world!", :routing_key => queue.name
|
117
|
-
end
|
118
|
-
</code>
|
119
|
-
</pre>
|
114
|
+
(if the example above isn't displayed, see this "gist":https://gist.github.com/998690)
|
120
115
|
|
121
116
|
This example demonstrates a very common communication scenario: app A wants to publish a message that will end up in
|
122
117
|
a queue that app B listens on. In this example, queue name is "amqpgem.examples.hello". Lets go through this example
|
@@ -214,86 +209,28 @@ as message's routing key. This is how our message ends up in amqpgem.examples.he
|
|
214
209
|
|
215
210
|
This first example can be modified to use method chaining technique:
|
216
211
|
|
217
|
-
<
|
218
|
-
<code>
|
219
|
-
#!/usr/bin/env ruby
|
220
|
-
# encoding: utf-8
|
221
|
-
|
222
|
-
require "rubygems"
|
223
|
-
require "amqp"
|
224
|
-
|
225
|
-
EventMachine.run do
|
226
|
-
AMQP.connect(:host => '127.0.0.1') do |connection|
|
227
|
-
puts "Connected to AMQP broker. Running #{AMQP::VERSION} version of the gem..."
|
228
|
-
|
229
|
-
channel = AMQP::Channel.new(connection)
|
212
|
+
<script src="https://gist.github.com/998691.js"> </script>
|
230
213
|
|
231
|
-
|
232
|
-
puts "Received a message: #{payload}. Disconnecting..."
|
233
|
-
|
234
|
-
connection.close {
|
235
|
-
EM.stop { exit }
|
236
|
-
}
|
237
|
-
end
|
238
|
-
|
239
|
-
channel.direct("").publish "Hello, world!", :routing_key => "amqpgem.examples.helloworld"
|
240
|
-
end
|
241
|
-
end
|
242
|
-
</code>
|
243
|
-
</pre>
|
214
|
+
(if the example above isn't displayed, see this "gist":https://gist.github.com/998691)
|
244
215
|
|
245
216
|
With classes and methods introduced in this example, lets move on to a little bit more
|
246
217
|
sophisticated one.
|
247
218
|
|
248
219
|
|
249
|
-
h2.
|
220
|
+
h2. Blabblr: one-to-many publish/subscribe example
|
250
221
|
|
251
222
|
Previous example demonstrated how connection to the broker is made and how to do 1:1 communication
|
252
223
|
using default exchange. Now lets take a look at another common scenario: broadcast, or multiple consumers
|
253
224
|
and one producer.
|
254
225
|
|
255
226
|
A very well know example of broadcast is Twitter: every time a person tweets, followers receive a notification.
|
256
|
-
Blabbr, our imaginary information network, models this scenario
|
227
|
+
Blabbr, our imaginary information network, models this scenario: every network member has a separate
|
257
228
|
queue and publishes blabs to a separate exchange. 3 Blabbr members, Joe, Aaron and Bob, follow official NBA
|
258
229
|
account on Blabbr to get updates about what is up in the world of basketball. Here is the code:
|
259
230
|
|
260
|
-
<
|
261
|
-
<code>
|
262
|
-
#!/usr/bin/env ruby
|
263
|
-
# encoding: utf-8
|
264
|
-
|
265
|
-
require "rubygems"
|
266
|
-
require "amqp"
|
267
|
-
|
268
|
-
AMQP.start("amqp://dev.rabbitmq.com:5672") do |connection|
|
269
|
-
channel = AMQP::Channel.new(connection)
|
270
|
-
exchange = channel.fanout("nba.scores")
|
271
|
-
|
272
|
-
channel.queue("joe", :auto_delete => true).bind(exchange).subscribe do |payload|
|
273
|
-
puts "#{payload} => joe"
|
274
|
-
end
|
275
|
-
|
276
|
-
channel.queue("aaron", :auto_delete => true).bind(exchange).subscribe do |payload|
|
277
|
-
puts "#{payload} => aaron"
|
278
|
-
end
|
279
|
-
|
280
|
-
channel.queue("bob", :auto_delete => true).bind(exchange).subscribe do |payload|
|
281
|
-
puts "#{payload} => bob"
|
282
|
-
end
|
283
|
-
|
284
|
-
exchange.publish("BOS 101, NYK 89").publish("ORL 85, ALT 88")
|
231
|
+
<script src="https://gist.github.com/998692.js"> </script>
|
285
232
|
|
286
|
-
|
287
|
-
EventMachine.add_timer(1) do
|
288
|
-
exchange.delete
|
289
|
-
|
290
|
-
connection.close {
|
291
|
-
EM.stop { exit }
|
292
|
-
}
|
293
|
-
end
|
294
|
-
end
|
295
|
-
</code>
|
296
|
-
</pre>
|
233
|
+
(if the example above isn't displayed, see this "gist":https://gist.github.com/998692)
|
297
234
|
|
298
235
|
First line has a few difference from "Hello, world" example above:
|
299
236
|
|
@@ -398,66 +335,9 @@ on North America updates list.
|
|
398
335
|
|
399
336
|
Here is the code:
|
400
337
|
|
401
|
-
<
|
402
|
-
<code>
|
403
|
-
#!/usr/bin/env ruby
|
404
|
-
# encoding: utf-8
|
338
|
+
<script src="https://gist.github.com/998694.js"> </script>
|
405
339
|
|
406
|
-
|
407
|
-
require "amqp"
|
408
|
-
|
409
|
-
EventMachine.run do
|
410
|
-
AMQP.connect do |connection|
|
411
|
-
channel = AMQP::Channel.new(connection)
|
412
|
-
exchange = channel.topic("pub/sub", :auto_delete => true)
|
413
|
-
|
414
|
-
# Subscribers.
|
415
|
-
channel.queue("", :exclusive => true) do |queue|
|
416
|
-
queue.bind(exchange, :routing_key => "americas.north.#").subscribe do |headers, payload|
|
417
|
-
puts "An update for North America: #{payload}, routing key is #{headers.routing_key}"
|
418
|
-
end
|
419
|
-
end
|
420
|
-
channel.queue("americas.south").bind(exchange, :routing_key => "americas.south.#").subscribe do |headers, payload|
|
421
|
-
puts "An update for South America: #{payload}, routing key is #{headers.routing_key}"
|
422
|
-
end
|
423
|
-
channel.queue("us.california").bind(exchange, :routing_key => "americas.north.us.ca.*").subscribe do |headers, payload|
|
424
|
-
puts "An update for US/California: #{payload}, routing key is #{headers.routing_key}"
|
425
|
-
end
|
426
|
-
channel.queue("us.tx.austin").bind(exchange, :routing_key => "#.tx.austin").subscribe do |headers, payload|
|
427
|
-
puts "An update for Austin, TX: #{payload}, routing key is #{headers.routing_key}"
|
428
|
-
end
|
429
|
-
channel.queue("it.rome").bind(exchange, :routing_key => "europe.italy.rome").subscribe do |headers, payload|
|
430
|
-
puts "An update for Rome, Italy: #{payload}, routing key is #{headers.routing_key}"
|
431
|
-
end
|
432
|
-
channel.queue("asia.hk").bind(exchange, :routing_key => "asia.southeast.hk.#").subscribe do |headers, payload|
|
433
|
-
puts "An update for Hong Kong: #{payload}, routing key is #{headers.routing_key}"
|
434
|
-
end
|
435
|
-
|
436
|
-
EM.add_timer(1) do
|
437
|
-
exchange.publish("San Diego update", :routing_key => "americas.north.us.ca.sandiego").
|
438
|
-
publish("Berkeley update", :routing_key => "americas.north.us.ca.berkeley").
|
439
|
-
publish("San Francisco update", :routing_key => "americas.north.us.ca.sanfrancisco").
|
440
|
-
publish("New York update", :routing_key => "americas.north.us.ny.newyork").
|
441
|
-
publish("São Paolo update", :routing_key => "americas.south.brazil.saopaolo").
|
442
|
-
publish("Hong Kong update", :routing_key => "asia.southeast.hk.hongkong").
|
443
|
-
publish("Kyoto update", :routing_key => "asia.southeast.japan.kyoto").
|
444
|
-
publish("Shanghai update", :routing_key => "asia.southeast.prc.shanghai").
|
445
|
-
publish("Rome update", :routing_key => "europe.italy.roma").
|
446
|
-
publish("Paris update", :routing_key => "europe.france.paris")
|
447
|
-
end
|
448
|
-
|
449
|
-
|
450
|
-
show_stopper = Proc.new {
|
451
|
-
connection.close do
|
452
|
-
EM.stop
|
453
|
-
end
|
454
|
-
}
|
455
|
-
|
456
|
-
EM.add_timer(2, show_stopper)
|
457
|
-
end
|
458
|
-
end
|
459
|
-
</code>
|
460
|
-
</pre>
|
340
|
+
(if the example above isn't displayed, see this "gist":https://gist.github.com/998694)
|
461
341
|
|
462
342
|
First line that is different from Blabbr example is
|
463
343
|
|
@@ -568,7 +448,7 @@ This tutorial ends here. Congratulations! You have learned quite a bit about bot
|
|
568
448
|
|
569
449
|
h2. What to read next
|
570
450
|
|
571
|
-
Documentation is organized as a {file:docs/DocumentationGuidesIndex.textile
|
451
|
+
Documentation is organized as a number of {file:docs/DocumentationGuidesIndex.textile documentation guides}, covering all kinds of
|
572
452
|
topics from {file:docs/Routing.textile routing} to {file:docs/ErrorHandling.textile error handling} to
|
573
453
|
{file:docs/VendorSpecificExchanges.textile Broker-specific AMQP 0.9.1 extensions}.
|
574
454
|
|
@@ -590,3 +470,21 @@ what was unclear? what wasn't covered? maybe you don't like guide style or gramm
|
|
590
470
|
key to making documentation better.
|
591
471
|
|
592
472
|
If mailing list communication is not an option for you for some reason, you can "contact guides author directly":mailto:michael@novemberain.com?subject=amqp%20gem%20documentation
|
473
|
+
|
474
|
+
|
475
|
+
<div id="disqus_thread"></div>
|
476
|
+
<script type="text/javascript">
|
477
|
+
/* * * CONFIGURATION VARIABLES * * */
|
478
|
+
var disqus_shortname = 'rubyamqpdocs'; // required: replace example with your forum shortname
|
479
|
+
|
480
|
+
var disqus_developer = 0; // set to 1 on local machine for testing comments
|
481
|
+
var disqus_identifier = 'amqp_connecting_to_the_broker';
|
482
|
+
var disqus_url = 'http://rdoc.info/github/ruby-amqp/amqp/master/file/docs/GettingStarted.textile';
|
483
|
+
|
484
|
+
/* * * DON'T EDIT BELOW THIS LINE * * */
|
485
|
+
(function() {
|
486
|
+
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
487
|
+
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
|
488
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
489
|
+
})();
|
490
|
+
</script>
|