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.
Files changed (152) hide show
  1. data/.rspec +2 -1
  2. data/.travis.yml +8 -2
  3. data/.yardopts +1 -0
  4. data/CHANGELOG +9 -0
  5. data/Gemfile +17 -11
  6. data/README.md +26 -16
  7. data/amqp.gemspec +2 -2
  8. data/bin/ci/before_build.sh +21 -0
  9. data/docs/08Migration.textile +199 -5
  10. data/docs/AMQP091ModelExplained.textile +322 -0
  11. data/docs/Bindings.textile +24 -4
  12. data/docs/Clustering.textile +1 -1
  13. data/docs/ConnectingToTheBroker.textile +98 -82
  14. data/docs/ConnectionEncryptionWithTLS.textile +65 -5
  15. data/docs/DocumentationGuidesIndex.textile +93 -13
  16. data/docs/Durability.textile +1 -1
  17. data/docs/ErrorHandling.textile +458 -94
  18. data/docs/Exchanges.textile +901 -87
  19. data/docs/GettingStarted.textile +278 -143
  20. data/docs/PatternsAndUseCases.textile +420 -0
  21. data/docs/Queues.textile +730 -178
  22. data/docs/RabbitMQVersions.textile +18 -3
  23. data/docs/RunningTests.textile +1 -1
  24. data/docs/TestingWithEventedSpec.textile +121 -0
  25. data/docs/Troubleshooting.textile +15 -1
  26. data/docs/VendorSpecificExtensions.textile +1 -1
  27. data/docs/diagrams/001_hello_world_example_routing.png +0 -0
  28. data/docs/diagrams/002_blabbr_example_routing.png +0 -0
  29. data/docs/diagrams/003_weathr_example_routing.png +0 -0
  30. data/docs/diagrams/004_fanout_exchange.png +0 -0
  31. data/docs/diagrams/005_direct_exchange.png +0 -0
  32. data/docs/diagrams/redhat/direct_exchange.png +0 -0
  33. data/docs/diagrams/redhat/fanout_exchange.png +0 -0
  34. data/docs/diagrams/redhat/topic_exchange.png +0 -0
  35. data/examples/error_handling/automatic_recovery_of_channel_and_queues.rb +50 -0
  36. data/examples/error_handling/automatically_recovering_hello_world_consumer.rb +51 -0
  37. data/examples/error_handling/automatically_recovering_hello_world_consumer_that_uses_a_server_named_queue.rb +51 -0
  38. data/examples/error_handling/basic_connection_failover.rb +22 -0
  39. data/examples/error_handling/channel_level_exception.rb +9 -2
  40. data/examples/error_handling/connection_level_exception.rb +8 -1
  41. data/examples/error_handling/connection_level_exception_with_objects.rb +49 -0
  42. data/examples/error_handling/connection_loss_handler.rb +1 -5
  43. data/examples/error_handling/hello_world_producer.rb +43 -0
  44. data/examples/error_handling/insufficient_permissions.rb +54 -0
  45. data/examples/error_handling/manual_connection_and_channel_recovery.rb +71 -0
  46. data/examples/error_handling/queue_exclusivity_violation.rb +41 -0
  47. data/examples/error_handling/queue_name_violation.rb +31 -0
  48. data/examples/exchanges/autodeletion_of_exchanges.rb +1 -4
  49. data/examples/guides/queues/01a_declaring_a_server_named_queue_using_queue_constructor.rb +7 -8
  50. data/examples/guides/queues/01b_declaring_a_queue_using_queue_constructor.rb +7 -8
  51. data/examples/guides/queues/02a_declaring_a_durable_shared_queue.rb +5 -8
  52. data/examples/guides/queues/02b_declaring_a_durable_shared_queue.rb +5 -8
  53. data/examples/guides/queues/03a_declaring_a_temporary_exclusive_queue.rb +7 -8
  54. data/examples/guides/queues/04_bind_a_queue_using_exchange_instance.rb +9 -10
  55. data/examples/guides/queues/05_bind_a_queue_using_exchange_name.rb +8 -10
  56. data/examples/guides/queues/06_subscribe_to_receive_messages.rb +10 -12
  57. data/examples/guides/queues/07_fetch_a_message_from_the_queue.rb +14 -14
  58. data/examples/guides/queues/08_unsubscribing_a_consumer.rb +13 -16
  59. data/examples/guides/queues/09_unbinding_from_exchange.rb +16 -22
  60. data/examples/guides/queues/10_purge_a_queue.rb +13 -18
  61. data/examples/guides/queues/11_deleting_a_queue.rb +14 -19
  62. data/examples/guides/queues/12_objects_that_consume_messages.rb +69 -0
  63. data/examples/guides/queues/13_objects_that_consume_messages_take_two.rb +89 -0
  64. data/examples/hello_world.rb +1 -3
  65. data/examples/hello_world_with_an_empty_string.rb +5 -6
  66. data/examples/inspecting_server_information.rb +45 -0
  67. data/examples/issues/issue_93.rb +23 -0
  68. data/examples/issues/issue_94.rb +23 -0
  69. data/examples/patterns/command/consumer.rb +45 -0
  70. data/examples/patterns/command/producer.rb +26 -0
  71. data/examples/patterns/request_reply/client.rb +29 -0
  72. data/examples/patterns/request_reply/server.rb +26 -0
  73. data/examples/publishing/publishing_a_one_off_message.rb +6 -4
  74. data/examples/publishing/returned_messages.rb +2 -10
  75. data/examples/queues/accessing_message_metadata.rb +15 -13
  76. data/examples/queues/queue_status.rb +12 -15
  77. data/examples/routing/fanout_routing.rb +33 -0
  78. data/examples/routing/headers_routing.rb +17 -15
  79. data/examples/routing/round_robin_with_direct_exchange.rb +39 -0
  80. data/examples/routing/round_robin_with_the_default_exchange.rb +38 -0
  81. data/examples/routing/unroutable_mandatory_message_is_returned.rb +33 -0
  82. data/examples/routing/weather_updates.rb +15 -20
  83. data/examples/tls/using_tls.rb +41 -0
  84. data/lib/amqp/bit_set.rb +80 -0
  85. data/lib/amqp/broker.rb +72 -0
  86. data/lib/amqp/channel.rb +93 -13
  87. data/lib/amqp/client.rb +11 -22
  88. data/lib/amqp/compatibility/ruby187_patchlevel_check.rb +2 -0
  89. data/lib/amqp/connection.rb +2 -3
  90. data/lib/amqp/consumer.rb +208 -0
  91. data/lib/amqp/deprecated/fork.rb +2 -0
  92. data/lib/amqp/deprecated/mq.rb +2 -0
  93. data/lib/amqp/exchange.rb +6 -4
  94. data/lib/amqp/extensions/rabbitmq.rb +3 -1
  95. data/lib/amqp/header.rb +76 -14
  96. data/lib/amqp/int_allocator.rb +96 -0
  97. data/lib/amqp/logger.rb +2 -0
  98. data/lib/amqp/queue.rb +242 -86
  99. data/lib/amqp/rpc.rb +2 -0
  100. data/lib/amqp/session.rb +169 -9
  101. data/lib/amqp/utilities/event_loop_helper.rb +2 -0
  102. data/lib/amqp/utilities/server_type.rb +2 -0
  103. data/lib/amqp/version.rb +2 -2
  104. data/lib/mq.rb +4 -2
  105. data/lib/mq/logger.rb +3 -1
  106. data/lib/mq/rpc.rb +3 -1
  107. data/spec/integration/authentication_spec.rb +17 -10
  108. data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +1 -1
  109. data/spec/integration/automatic_recovery_predicate_spec.rb +68 -0
  110. data/spec/integration/basic_get_spec.rb +2 -1
  111. data/spec/integration/{extensions/basic_return_spec.rb → basic_return_spec.rb} +2 -1
  112. data/spec/integration/channel_level_exception_handling_spec.rb +53 -0
  113. data/spec/integration/connection_level_exception_handling_spec.rb +49 -0
  114. data/spec/integration/declare_and_immediately_bind_a_server_named_queue_spec.rb +38 -17
  115. data/spec/integration/declare_one_hundred_server_named_queues_spec.rb +44 -0
  116. data/spec/integration/direct_exchange_routing_spec.rb +125 -0
  117. data/spec/integration/exchange_declaration_spec.rb +75 -46
  118. data/spec/integration/extensions/rabbitmq/publisher_confirmations_spec.rb +180 -0
  119. data/spec/integration/{workload_distribution_spec.rb → fanout_exchange_routing_spec.rb} +10 -9
  120. data/spec/integration/headers_exchange_routing_spec.rb +269 -0
  121. data/spec/integration/hello_world_spec.rb +77 -0
  122. data/spec/integration/immediate_messages_spec.rb +59 -0
  123. data/spec/integration/mandatory_messages_spec.rb +52 -0
  124. data/spec/integration/message_metadata_access_spec.rb +106 -0
  125. data/spec/integration/multiple_consumers_per_queue_spec.rb +319 -0
  126. data/spec/integration/ordering_of_published_messages_spec.rb +96 -0
  127. data/spec/integration/queue_declaration_spec.rb +8 -8
  128. data/spec/integration/queue_status_spec.rb +66 -0
  129. data/spec/integration/recovery/per_channel_automatic_recovery_on_graceful_broker_shutdown_spec.rb +76 -0
  130. data/spec/integration/recovery/per_channel_automatic_recovery_spec.rb +72 -0
  131. data/spec/integration/redelivery_of_unacknowledged_messages_spec.rb +96 -0
  132. data/spec/integration/regressions/concurrent_publishing_on_the_same_channel_spec.rb +91 -0
  133. data/spec/integration/regressions/empty_message_body_spec.rb +56 -0
  134. data/spec/integration/regressions/issue66_spec.rb +2 -1
  135. data/spec/integration/reply_queue_communication_spec.rb +2 -1
  136. data/spec/integration/store_and_forward_spec.rb +4 -3
  137. data/spec/integration/topic_subscription_spec.rb +2 -1
  138. data/spec/integration/tx_commit_spec.rb +124 -0
  139. data/spec/integration/tx_rollback_spec.rb +167 -0
  140. data/spec/spec_helper.rb +44 -71
  141. data/spec/unit/amqp/bit_set_spec.rb +127 -0
  142. data/spec/unit/amqp/channel_id_allocation_spec.rb +40 -0
  143. data/spec/unit/amqp/connection_spec.rb +4 -2
  144. data/spec/unit/amqp/int_allocator_spec.rb +116 -0
  145. metadata +92 -26
  146. data/CONTRIBUTORS +0 -29
  147. data/docs/Routing.textile +0 -30
  148. data/examples/real-world/task-queue/README.textile +0 -3
  149. data/examples/real-world/task-queue/consumer.rb +0 -27
  150. data/examples/real-world/task-queue/producer.rb +0 -22
  151. data/spec/unit/amqp/basic_spec.rb +0 -39
  152. data/tasks.rb +0 -4
@@ -10,18 +10,33 @@ This guide covers compatibility of the "Ruby amqp gem":http://github.com/ruby-am
10
10
 
11
11
  h2. Covered versions
12
12
 
13
- This guide covers "Ruby amqp gem":http://github.com/ruby-amqp/amqp v0.6.0 and later.
13
+ This guide covers "Ruby amqp gem":http://github.com/ruby-amqp/amqp v0.8.0 and later.
14
14
 
15
15
 
16
16
 
17
17
  h2. Using recent versions on Debian and Ubuntu
18
18
 
19
- Ubuntu (even 10.10) and Debian both "ship with old RabbitMQ version":http://packages.ubuntu.com/maverick/rabbitmq-server,
19
+ Ubuntu (even 10.10) and Debian both "ship with an old RabbitMQ version":http://packages.ubuntu.com/maverick/rabbitmq-server,
20
20
  that only supports AMQP protocol 0.8. Ruby amqp gem 0.8.0 and later *will not work with RabbitMQ versions before 2.0.0*.
21
21
 
22
22
  We strongly recommend that you use "RabbitMQ apt repository":http://www.rabbitmq.com/debian.html#apt that has recent versions of RabbitMQ.
23
23
 
24
24
 
25
+ h3. Chef cookbook for RabbitMQ
26
+
27
+ There is a "Chef cookbook for RabbitMQ":https://github.com/opscode/cookbooks/tree/master/rabbitmq that installs recent versions from
28
+ the rabbitmq.com apt repository. It also has LWPRs (providers) for managing users and vhosts.
29
+
30
+
31
+ h3. RabbitMQ Puppet module
32
+
33
+ There is a "RabbitMQ Puppet module":https://github.com/puppetlabs/puppetlabs-rabbitmq by the Puppet Labs team. It uses .deb packages from
34
+ Debian testing and unstable repositories. Note that it has two dependencies:
35
+
36
+ * "puppet-stdlib":https://github.com/puppetlabs/puppetlabs-stdlib
37
+ * "puppet-apt":https://github.com/puppetlabs/puppet-apt
38
+
39
+
25
40
 
26
41
  h2. TLS (SSL) support
27
42
 
@@ -37,7 +52,7 @@ and recommends using Erlang R141B that ships with Erlang SSL 4.0.1.
37
52
 
38
53
  h2. Tell us what you think!
39
54
 
40
- Please take a moment and tell us what you think about this guide on "Ruby AMQP mailing list":http://groups.google.com/group/ruby-amqp:
55
+ Please take a moment and tell us what you think about this guide "on Twitter":http://twitter.com/rubyamqp or "Ruby AMQP mailing list":http://groups.google.com/group/ruby-amqp:
41
56
  what was unclear? what wasn't covered? maybe you don't like guide style or grammar and spelling are incorrect? Readers feedback is
42
57
  key to making documentation better.
43
58
 
@@ -90,7 +90,7 @@ add more implementations/versions so easily it still seems unreal.
90
90
 
91
91
  h2. Tell us what you think!
92
92
 
93
- Please take a moment and tell us what you think about this guide on "Ruby AMQP mailing list":http://groups.google.com/group/ruby-amqp:
93
+ Please take a moment and tell us what you think about this guide "on Twitter":http://twitter.com/rubyamqp or "Ruby AMQP mailing list":http://groups.google.com/group/ruby-amqp:
94
94
  what was unclear? what wasn't covered? maybe you don't like guide style or grammar and spelling are incorrect? Readers feedback is
95
95
  key to making documentation better.
96
96
 
@@ -0,0 +1,121 @@
1
+ # @title Ruby AMQP gem: Testing with Evented spec
2
+
3
+ h1. Testing you applications with evented-spec
4
+
5
+
6
+ h2. About this guide
7
+
8
+ This guide covers writing tests with evented-spec for amqp-based applications.
9
+
10
+
11
+ h2. Covered versions
12
+
13
+ This guide covers "Ruby amqp gem":http://github.com/ruby-amqp/amqp v0.8.0 and later.
14
+ Also covered is the "evented-spec gem":http://github.com/ruby-amqp/evented-spec v0.4.1 and later.
15
+
16
+ h2. Rationale
17
+
18
+ Asynchronous environments are somewhat more difficult to test.
19
+ There are two different approaches to testing them:
20
+
21
+ * Stubbing out a big chunk of the environment
22
+ * Using the "real" environment
23
+
24
+ First approach is risky because your application becomes divorced from reality and what *really* happens.
25
+ Second approach is more "correct", but at the same time much more tedious, because there are a lot of things to wrap your head around: initial setup, error handling,
26
+ in case of amqp, also connection starting.
27
+
28
+ However, tediousness for most part can be easily fought with proper helpers and organization. evented-spec gem
29
+ (based on arvicco's amqp-spec and tmmm1's em-spec) provides this kind of helpers for your asynchronous applications.
30
+
31
+ This guide covers usage of that gem in context of amqp but there are all the parts for testing EM-based and Cool.io-based applications.
32
+
33
+ h2. Using evented-spec
34
+
35
+ h3. Setting up
36
+
37
+ To start using amqp all you need is to include <code>EventedSpec::AMQPSpec</code> module into your context and add <code>#done</code>
38
+ calls to your examples:
39
+
40
+ <script src="https://gist.github.com/1027377.js"></script>
41
+
42
+ h3. Implications of asynchronous environment (or why we need #done)
43
+
44
+ Since we are using callback mechanisms in order to provide asynchronicity, we have to deal with situation when we expect a response,
45
+ and response never comes. Usual solution includes setting a timeout which makes the given tests fail if they aren't finished in a timely
46
+ manner. When <code>#done</code> is called, your tests confirm successful ending of specs. Try removing <code>done</code> from the above
47
+ example and see what happens. (spoiler: <code>EventedSpec::SpecHelper::SpecTimeoutExceededError: Example timed out</code>)
48
+
49
+ h3. Changing default connection options and default timeout
50
+
51
+ It is not uncommon to have custom options for your test environment. For example, setting up custom vhost and timeout:
52
+
53
+ <script src="https://gist.github.com/1027410.js"> </script>
54
+
55
+ Options are the same as used in <code>AMQP.connect</code>.
56
+
57
+ h3. Callbacks
58
+
59
+ evented-spec provides various callbacks similar to rspec's <code>before(:each)</code> / <code>after(:each)</code>. They are called <code>amqp_before</code> and
60
+ <code>amqp_after</code> and happen right after connection is established or before connection is closed. It is a good place to put your channel initialization routines.
61
+
62
+ h3. Example of a meaningful spec
63
+
64
+ Now that you're filled on theory part, it's time to do something with all this knowledge. Below goes a slightly modified version of one of the integration specs from AMQP
65
+ suite. It sets up default topic exchange and publishes various messages about sports events:
66
+
67
+ <script src="https://gist.github.com/1027478.js"> </script>
68
+
69
+ Couple of things to notice: <code>#done</code> is invoked using an optional callback and optional delay, also instance variables behavior in hooks is the same as in "normal" rspec
70
+ hooks.
71
+
72
+ h3. Using #delayed in your specs
73
+
74
+ AMQP gem uses "EventMachine":http://eventmachine.rubyforge.org/ under hood. If you don't know about eventmachine, you can read more about it on the official site.
75
+ What's important for us is that you *cannot use <code>sleep</code> for delays*. Why? Because all the specs code is processed directly in the "reactor":http://en.wikipedia.org/wiki/Reactor_pattern thread, if you
76
+ <code>sleep</code> in that thread, reactor cannot send frames. What you need to use instead is <code>#delayed</code> method. It takes delay time in seconds and callback
77
+ which it launches once that time passes. Basic usage is either <code>sleep</code> replacement or ensuring certain order of execution (though, the latter should not bother
78
+ you too much). You can also use it to cleanup your environment after tests if any is needed.
79
+
80
+ In the following example, we declare two channels, then declare the same queue twice with the same name but different options (which raises a channel-level exception in AMQP):
81
+
82
+ <script src="https://gist.github.com/1027500.js"> </script>
83
+
84
+ If you draw a timeline, various events happen at 0.0s, then at 0.1s, then at 0.3s and eventually at 0.4s.
85
+
86
+ h3. What happens under hood
87
+
88
+ When you include <code>EventedSpec::AMQPSpec</code> module, <code>#it</code> calls are wrapped in <code>EM.start</code> + <code>AMQP.connect</code>
89
+ calls, so you can start writing your examples as if you're connected. You still need to initialize your own channel though.
90
+
91
+
92
+ h2. What to read next
93
+
94
+ There is a lot more to evented-spec than described in this guide. evented-spec has "rdocs":http://rdoc.info/github/ruby-amqp/evented-spec/master,
95
+ which I strongly suggest to read in case you don't understand some parts of the gem.
96
+
97
+ h2. Tell us what you think!
98
+
99
+ Please take a moment and tell us what you think about this guide "on Twitter":http://twitter.com/rubyamqp or "Ruby AMQP mailing list":http://groups.google.com/group/ruby-amqp:
100
+ what was unclear? what wasn't covered? maybe you don't like guide style or grammar and spelling are incorrect? Readers feedback is
101
+ key to making documentation better.
102
+
103
+ 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
104
+
105
+
106
+ <div id="disqus_thread"></div>
107
+ <script type="text/javascript">
108
+ /* * * CONFIGURATION VARIABLES * * */
109
+ var disqus_shortname = 'rubyamqpdocs'; // required: replace example with your forum shortname
110
+
111
+ var disqus_developer = 0; // set to 1 on local machine for testing comments
112
+ var disqus_identifier = 'amqp_testing_with_evented_spec';
113
+ var disqus_url = 'http://rdoc.info/github/ruby-amqp/amqp/master/file/docs/TestingWithEventedSpec.textile';
114
+
115
+ /* * * DON'T EDIT BELOW THIS LINE * * */
116
+ (function() {
117
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
118
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
119
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
120
+ })();
121
+ </script>
@@ -103,10 +103,24 @@ it is a good idea to check these two things first:
103
103
 
104
104
 
105
105
 
106
+ h2. Broker Startup Issues
107
+
108
+ h3. Missing erlang-os-mon on Debian and Ubuntu
109
+
110
+ The following error on RabbitMQ startup on Debian or Ubuntu
111
+
112
+ <pre>
113
+ ERROR: failed to load application os_mon: {"no such file or directory","os_mon.app"}
114
+ </pre>
115
+
116
+ suggests that *erlang-os-mon* package is not installed.
117
+
118
+
119
+
106
120
 
107
121
  h2. Tell us what you think!
108
122
 
109
- Please take a moment and tell us what you think about this guide on "Ruby AMQP mailing list":http://groups.google.com/group/ruby-amqp:
123
+ Please take a moment and tell us what you think about this guide "on Twitter":http://twitter.com/rubyamqp or "Ruby AMQP mailing list":http://groups.google.com/group/ruby-amqp:
110
124
  what was unclear? what wasn't covered? maybe you don't like guide style or grammar and spelling are incorrect? Readers feedback is
111
125
  key to making documentation better.
112
126
 
@@ -37,7 +37,7 @@ RabbitMQ extensions documentation is part of "amq-client gem documentation":http
37
37
 
38
38
  h2. Tell us what you think!
39
39
 
40
- Please take a moment and tell us what you think about this guide on "Ruby AMQP mailing list":http://groups.google.com/group/ruby-amqp:
40
+ Please take a moment and tell us what you think about this guide "on Twitter":http://twitter.com/rubyamqp or "Ruby AMQP mailing list":http://groups.google.com/group/ruby-amqp:
41
41
  what was unclear? what wasn't covered? maybe you don't like guide style or grammar and spelling are incorrect? Readers feedback is
42
42
  key to making documentation better.
43
43
 
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require "bundler"
5
+ Bundler.setup
6
+
7
+ $:.unshift(File.expand_path("../../../lib", __FILE__))
8
+
9
+ require 'amqp'
10
+
11
+
12
+ puts "=> Example of automatic AMQP channel and queues recovery"
13
+ puts
14
+ AMQP.start(:host => "localhost") do |connection, open_ok|
15
+ connection.on_error do |ch, connection_close|
16
+ raise connection_close.reply_text
17
+ end
18
+
19
+ ch1 = AMQP::Channel.new(connection, 2, :auto_recovery => true)
20
+ ch1.on_error do |ch, channel_close|
21
+ raise channel_close.reply_text
22
+ end
23
+
24
+ if ch1.auto_recovering?
25
+ puts "Channel #{ch1.id} IS auto-recovering"
26
+ end
27
+
28
+ connection.on_tcp_connection_loss do |conn, settings|
29
+ puts "[network failure] Trying to reconnect..."
30
+ conn.reconnect(false, 2)
31
+ end
32
+
33
+
34
+ ch1.queue("amqpgem.examples.queue1", :auto_delete => true).bind("amq.fanout")
35
+ ch1.queue("amqpgem.examples.queue2", :auto_delete => true).bind("amq.fanout")
36
+ ch1.queue("amqpgem.examples.queue3", :auto_delete => true).bind("amq.fanout").subscribe do |metadata, payload|
37
+ end
38
+
39
+
40
+ show_stopper = Proc.new {
41
+ connection.disconnect { puts "Disconnected. Exiting…"; EventMachine.stop }
42
+ }
43
+
44
+ Signal.trap "TERM", show_stopper
45
+ Signal.trap "INT", show_stopper
46
+ EM.add_timer(30, show_stopper)
47
+
48
+
49
+ puts "Connected, authenticated. To really exercise this example, shut AMQP broker down for a few seconds. If you don't it will exit gracefully in 30 seconds."
50
+ end
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require "bundler"
5
+ Bundler.setup
6
+
7
+ $:.unshift(File.expand_path("../../../lib", __FILE__))
8
+
9
+ require 'amqp'
10
+
11
+ puts "=> Example of automatic AMQP channel and queues recovery"
12
+ puts
13
+ AMQP.start(:host => "localhost") do |connection, open_ok|
14
+ connection.on_error do |ch, connection_close|
15
+ raise connection_close.reply_text
16
+ end
17
+
18
+ ch1 = AMQP::Channel.new(connection, 2, :auto_recovery => true)
19
+ ch1.on_error do |ch, channel_close|
20
+ raise channel_close.reply_text
21
+ end
22
+
23
+ connection.on_tcp_connection_loss do |conn, settings|
24
+ puts "[network failure] Trying to reconnect..."
25
+ conn.reconnect(false, 2)
26
+ end
27
+
28
+ queue = ch1.queue("amqpgem.examples.autorecovery.queue", :auto_delete => false, :durable => true).bind("amq.fanout")
29
+ queue.subscribe(:ack => true) do |metadata, payload|
30
+ puts "[consumer1] => #{payload}"
31
+ metadata.ack
32
+ end
33
+ consumer2 = AMQP::Consumer.new(ch1, queue)
34
+ consumer2.consume.on_delivery do |metadata, payload|
35
+ puts "[conusmer2] => #{payload}"
36
+ metadata.ack
37
+ end
38
+
39
+
40
+ show_stopper = Proc.new {
41
+ connection.disconnect { puts "Disconnected. Exiting…"; EventMachine.stop }
42
+ }
43
+
44
+ Signal.trap "TERM", show_stopper
45
+ Signal.trap "INT", show_stopper
46
+ EM.add_timer(45, show_stopper)
47
+
48
+
49
+ puts "This example needs another script/app to publish messages to amq.fanout. See examples/error_handling/hello_world_producer.rb for example"
50
+ puts "Connected, authenticated. To really exercise this example, shut AMQP broker down for a few seconds. If you don't it will exit gracefully in 45 seconds."
51
+ end
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require "bundler"
5
+ Bundler.setup
6
+
7
+ $:.unshift(File.expand_path("../../../lib", __FILE__))
8
+
9
+ require 'amqp'
10
+
11
+ puts "=> Example of automatic AMQP channel and queues recovery"
12
+ puts
13
+ AMQP.start(:host => "localhost") do |connection, open_ok|
14
+ connection.on_error do |ch, connection_close|
15
+ raise connection_close.reply_text
16
+ end
17
+
18
+ ch1 = AMQP::Channel.new(connection, 2, :auto_recovery => true)
19
+ ch1.on_error do |ch, channel_close|
20
+ raise channel_close.reply_text
21
+ end
22
+
23
+ connection.on_tcp_connection_loss do |conn, settings|
24
+ puts "[network failure] Trying to reconnect..."
25
+ conn.reconnect(false, 2)
26
+ end
27
+
28
+ queue = ch1.queue("", :auto_delete => true, :exclusive => true).bind("amq.fanout")
29
+ queue.subscribe(:ack => true) do |metadata, payload|
30
+ puts "[consumer1] => #{payload}"
31
+ metadata.ack
32
+ end
33
+ consumer2 = AMQP::Consumer.new(ch1, queue)
34
+ consumer2.consume.on_delivery do |metadata, payload|
35
+ puts "[conusmer2] => #{payload}"
36
+ metadata.ack
37
+ end
38
+
39
+
40
+ show_stopper = Proc.new {
41
+ connection.disconnect { puts "Disconnected. Exiting…"; EventMachine.stop }
42
+ }
43
+
44
+ Signal.trap "TERM", show_stopper
45
+ Signal.trap "INT", show_stopper
46
+ EM.add_timer(45, show_stopper)
47
+
48
+
49
+ puts "This example needs another script/app to publish messages to amq.fanout. See examples/error_handling/hello_world_producer.rb for example"
50
+ puts "Connected, authenticated. To really exercise this example, shut AMQP broker down for a few seconds. If you don't it will exit gracefully in 45 seconds."
51
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require "bundler"
5
+ Bundler.setup
6
+
7
+ $:.unshift(File.expand_path("../../../lib", __FILE__))
8
+
9
+ require 'amqp'
10
+
11
+ puts "=> Example of basic failover with AMQP::Session#reconnect_to"
12
+ puts
13
+ AMQP.start(:host => "localhost") do |connection, open_ok|
14
+ connection.on_recovery do |conn, settings|
15
+ puts "Connection recovered, now connected to dev.rabbitmq.com"
16
+ end
17
+
18
+ connection.on_tcp_connection_loss do |conn, settings|
19
+ puts "Trying to reconnect..."
20
+ conn.reconnect_to("amqp://dev.rabbitmq.com")
21
+ end
22
+ end
@@ -15,8 +15,15 @@ AMQP.start("amqp://guest:guest@dev.rabbitmq.com:5672") do |connection, open_ok|
15
15
  AMQP::Channel.new do |channel, open_ok|
16
16
  puts "Channel ##{channel.id} is now open!"
17
17
 
18
- channel.on_error do |ch, close|
19
- puts "Handling a channel-level exception: #{close.reply_text}"
18
+ channel.on_error do |ch, channel_close|
19
+ puts <<-ERR
20
+ Handling a channel-level exception.
21
+
22
+ AMQP class id : #{channel_close.class_id},
23
+ AMQP method id: #{channel_close.method_id},
24
+ Status code : #{channel_close.reply_code}
25
+ Error message : #{channel_close.reply_text}
26
+ ERR
20
27
  end
21
28
 
22
29
  EventMachine.add_timer(0.4) do
@@ -14,7 +14,14 @@ EventMachine.run do
14
14
 
15
15
 
16
16
  connection.on_error do |conn, connection_close|
17
- puts "Handling a connection-level exception: #{connection_close.reply_text}"
17
+ puts <<-ERR
18
+ Handling a connection-level exception.
19
+
20
+ AMQP class id : #{connection_close.class_id},
21
+ AMQP method id: #{connection_close.method_id},
22
+ Status code : #{connection_close.reply_code}
23
+ Error message : #{connection_close.reply_text}
24
+ ERR
18
25
 
19
26
  EventMachine.stop
20
27
  end