amqp 0.8.0.rc6 → 0.8.0.rc7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
25
25
 
26
26
  # Dependencies
27
27
  s.add_dependency "eventmachine"
28
- s.add_dependency "amq-client", ">= 0.7.0.alpha18"
28
+ s.add_dependency "amq-client", ">= 0.7.0.alpha20"
29
29
 
30
30
  begin
31
31
  require "changelog"
@@ -51,7 +51,37 @@ TBD
51
51
 
52
52
  h3. Publisher confirms
53
53
 
54
- TBD
54
+ Because transactions carry certain (for some applications, significant) overhead, RabbitMQ introduced an extension to AMQP 0.9.1
55
+ called {http://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms/ publisher confirms} ({http://www.rabbitmq.com/extensions.html#confirms documentation}).
56
+
57
+ amqp gem implements support for this extension, but it is not loaded by default when you require "amqp". To load it, use
58
+
59
+ <pre>
60
+ <code>
61
+ require "amqp/extensions/rabbitmq"
62
+ </code>
63
+ </pre>
64
+
65
+ and then define a callback for publisher confirms using {AMQP::Channel#confirm}:
66
+
67
+ <pre>
68
+ <code>
69
+ # enable publisher acknowledgements for this channel
70
+ channel.confirm_select
71
+
72
+ # define a callback that will be executed when message is acknowledged
73
+ channel.on_ack do |basic_ack|
74
+ puts "Received an acknowledgement: delivery_tag = #{basic_ack.delivery_tag}, multiple = #{basic_ack.multiple}"
75
+ end
76
+
77
+ # define a callback that will be executed when message is rejected using basic.nack (a RabbitMQ-specific extension)
78
+ channel.on_nack do |basic_nack|
79
+ puts "Received a nack: delivery_tag = #{basic_nack.delivery_tag}, multiple = #{basic_nack.multiple}"
80
+ end
81
+ </code>
82
+ </pre>
83
+
84
+ Note that the same callback is used for all messages published via all exchanges on the given channel.
55
85
 
56
86
 
57
87
  h3. Clustering
@@ -344,6 +344,11 @@ end
344
344
  </code>
345
345
  </pre>
346
346
 
347
+ In books, articles and documentation about AMQP 0.9.1 you may come around discussions of _consumer tags_. Consumer tag in AMQP
348
+ parlance is an identifier for subscription: most often, it is used to unsubscribe from messages (more on that later in this chapter).
349
+ If you need to obtain consumer tag of a queue that is subscribed to receive messages, use {AMQP::Queue#consumer_tag}.
350
+
351
+
347
352
  h3. Exclusive consumers
348
353
 
349
354
  TBD
@@ -394,7 +399,42 @@ TBD
394
399
 
395
400
  h2. Unsubscribing from messages
396
401
 
397
- TBD
402
+ Sometimes it is necessary to unsubscribe from messages without deleting a queue. To do that, use {AMQP::Queue#unsubscribe} method:
403
+
404
+ <pre>
405
+ <code>
406
+ #!/usr/bin/env ruby
407
+ # encoding: utf-8
408
+
409
+ require "rubygems"
410
+ require "amqp"
411
+
412
+ AMQP.start("amqp://guest:guest@dev.rabbitmq.com:5672/") do |connection, open_ok|
413
+ AMQP::Channel.new do |channel, open_ok|
414
+ exchange = channel.fanout("amq.fanout")
415
+
416
+ channel.queue("", :auto_delete => true, :exclusive => true) do |queue, declare_ok|
417
+ queue.bind(exchange).subscribe do |headers, payload|
418
+ puts "Received a new message"
419
+ end
420
+
421
+ EventMachine.add_timer(0.3) do
422
+ queue.unsubscribe
423
+ puts "Unsubscribed. Shutting down..."
424
+
425
+ connection.close {
426
+ EM.stop { exit }
427
+ }
428
+ end # EventMachine.add_timer
429
+ end # channel.queue
430
+ end
431
+ end
432
+ </code>
433
+ </pre>
434
+
435
+ By default {AMQP::Queue#unsubscribe} uses :noack option to inform broker that there is no need to send a
436
+ confirmation. In other words, it does not expect you to pass in a callback, because consumer tag and registered
437
+ callbacks are cleared immediately.
398
438
 
399
439
 
400
440
  h2. Unbinding queues from exchanges
@@ -13,13 +13,13 @@ AMQP.start do |connection|
13
13
  AMQP::Channel.new(connection) do |channel|
14
14
  puts "Channel #{channel.id} is now open"
15
15
 
16
- channel.confirmations
16
+ channel.confirm_select
17
17
  channel.on_error do
18
18
  puts "Oops, there is a channel-levle exceptions!"
19
19
  end
20
20
 
21
21
 
22
- channel.confirm do |basic_ack|
22
+ channel.on_ack do |basic_ack|
23
23
  puts "Received basic_ack: multiple = #{basic_ack.multiple}, delivery_tag = #{basic_ack.delivery_tag}"
24
24
  end
25
25
 
@@ -50,4 +50,4 @@ AMQP.start do |connection|
50
50
  EM.add_timer(3, show_stopper)
51
51
  Signal.trap('INT', show_stopper)
52
52
  Signal.trap('TERM', show_stopper)
53
- end
53
+ end
@@ -4,8 +4,7 @@
4
4
  require "rubygems"
5
5
  require "amqp"
6
6
 
7
- #AMQP.start("amqp://guest:guest@dev.rabbitmq.com:5672/") do |connection, open_ok|
8
- AMQP.start do |connection, open_ok|
7
+ AMQP.start("amqp://guest:guest@dev.rabbitmq.com:5672/") do |connection, open_ok|
9
8
  AMQP::Channel.new do |channel, open_ok|
10
9
  exchange = channel.fanout("amq.fanout")
11
10
 
@@ -15,14 +14,12 @@ AMQP.start do |connection, open_ok|
15
14
  end
16
15
 
17
16
  EventMachine.add_timer(0.3) do
18
- puts "Timer tick"
19
- queue.unsubscribe do |_|
20
- puts "Unsubscribed. Shutting down..."
17
+ queue.unsubscribe
18
+ puts "Unsubscribed. Shutting down..."
21
19
 
22
- connection.close {
23
- EM.stop { exit }
24
- }
25
- end
20
+ connection.close {
21
+ EM.stop { exit }
22
+ }
26
23
  end # EventMachine.add_timer
27
24
  end # channel.queue
28
25
  end
@@ -0,0 +1,37 @@
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
+ if RUBY_VERSION == "1.8.7"
12
+ class Array
13
+ alias sample choice
14
+ end
15
+ end
16
+
17
+ puts "=> Publishing and immediately stopping the event loop in the callback"
18
+ puts
19
+
20
+ # WARNING: this example is born out of http://bit.ly/j6v1Uz (#67) and
21
+ # by no means a demonstration of how you should go about publishing one-off messages.
22
+ # If durability is a concern, please read our "Durability and message persistence" guide at
23
+ # http://bit.ly/lQP1Al
24
+
25
+ EventMachine.run do
26
+ client = AMQP.connect(:host => '127.0.0.1')
27
+ channel = AMQP::Channel.new(client)
28
+ channel.on_error { puts 'channel error'; EM.stop }
29
+
30
+ queue = channel.queue("some_topic", :auto_delete => true)
31
+ exchange = channel.topic("foo", :durable => true, :auto_delete => true)
32
+
33
+ exchange.publish( 'hello world', :routing_key => "some_topic", :persistent => true, :nowait => false ) do
34
+ puts 'enqueued message for publishing on next event loop tick'
35
+ EventMachine.stop
36
+ end
37
+ end
@@ -364,6 +364,8 @@ module AMQP
364
364
  # and distributed to any active consumers. Routing logic is determined by exchange type and
365
365
  # configuration as well as message attributes (like :routing_key).
366
366
  #
367
+ #
368
+ #
367
369
  # h2. Data serialization
368
370
  #
369
371
  # Note that this method calls #to_s on payload argument value. You are encouraged to take care of
@@ -375,7 +377,30 @@ module AMQP
375
377
  #
376
378
  # h2. Event loop blocking
377
379
  #
378
- # To minimize blocking of EventMachine event loop, this method performs network I/O on the next event loop tick.
380
+ # To minimize blocking of EventMachine event loop, this method performs network I/O on the next event loop tick. This means
381
+ # that shutting down the event loop immediately after {Exchange#publish} returns will result in message never being sent.
382
+ # If you need to send a one-off message and then stop the event loop, pass a block to {Exchange#publish} that will be executed
383
+ # after message is pushed down the network stack, and use {AMQP::Session#disconnect} to properly tear down AMQP connection
384
+ # (see example under Examples section below).
385
+ #
386
+ # @example Publishing a one-off message and properly closing AMQP connection then stopping the event loop:
387
+ # exchange.publish(data) do
388
+ # connection.disconnect { EventMachine.stop }
389
+ # end
390
+ #
391
+ #
392
+ # h2. Publishing and persistence
393
+ #
394
+ # In cases when you application cannot afford to lose a message, AMQP 0.9.1 has several features to offer:
395
+ #
396
+ # * Persistent messages
397
+ # * Messages acknowledgements
398
+ # * Transactions
399
+ # * (a RabbitMQ-specific extension) Publisher confirms
400
+ #
401
+ # This is a broad topic and we dedicate a separate guide, {file:docs/Durability.textile Durability and message persistence}, to it.
402
+ #
403
+ #
379
404
  #
380
405
  # @param [#to_s] payload Message payload (content). Note that this method calls #to_s on payload argument value.
381
406
  # You are encouraged to take care of data serialization before publishing (using JSON, Thrift,
@@ -425,7 +450,11 @@ module AMQP
425
450
  opts = @default_publish_options.merge(options)
426
451
 
427
452
  @channel.once_open do
428
- super(payload.to_s, opts[:key] || opts[:routing_key] || @default_routing_key, @default_headers.merge(options), opts[:mandatory], opts[:immediate], &block)
453
+ super(payload.to_s, opts[:key] || opts[:routing_key] || @default_routing_key, @default_headers.merge(options), opts[:mandatory], opts[:immediate])
454
+
455
+ # don't pass block to AMQ::Client::Exchange#publish because it will be executed
456
+ # immediately and we want to do it later. See ruby-amqp/amqp/#67 MK.
457
+ block.call if block
429
458
  end
430
459
  end
431
460
 
@@ -573,7 +573,7 @@ module AMQP
573
573
  # The method accepts a block which will be executed when the
574
574
  # unsubscription request is acknowledged as complete by the server.
575
575
  #
576
- # @option opts [Boolean] :nowait (false) If set, the server will not respond to the method. The client should
576
+ # @option opts [Boolean] :nowait (true) If set, the server will not respond to the method. The client should
577
577
  # not wait for a reply method. If the server could not complete the
578
578
  # method it will raise a channel or connection exception.
579
579
  #
@@ -6,5 +6,5 @@ module AMQP
6
6
  #
7
7
  # @see AMQ::Protocol::VERSION
8
8
  # @return [String] AMQP gem version
9
- VERSION = '0.8.0.rc6'
9
+ VERSION = '0.8.0.rc7'
10
10
  end
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require "spec_helper"
3
3
 
4
- describe "Authentication attempt" do
4
+ describe "Immediate disconnection" do
5
5
 
6
6
  #
7
7
  # Environment
@@ -11,25 +11,14 @@ describe "Authentication attempt" do
11
11
  include EventedSpec::SpecHelper
12
12
 
13
13
 
14
- describe "with default connection parameters" do
14
+ after :all do
15
+ done
16
+ end
15
17
 
16
- #
17
- # Examples
18
- #
19
-
20
- # assuming there is an account guest with password of "guest" that has
21
- # access to / (default vhost)
22
- context "when guest/guest has access to /" do
23
- after :all do
24
- done
25
- end
26
-
27
- it "succeeds" do
28
- c = AMQP.connect
29
- c.disconnect
30
-
31
- done
32
- end # it
33
- end # context
34
- end # describe
18
+ it "succeeds" do
19
+ c = AMQP.connect
20
+ c.disconnect {
21
+ done
22
+ }
23
+ end # it
35
24
  end # describe "Authentication attempt"
metadata CHANGED
@@ -1,65 +1,49 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: amqp
3
- version: !ruby/object:Gem::Version
4
- hash: 977940491
5
- prerelease: true
6
- segments:
7
- - 0
8
- - 8
9
- - 0
10
- - rc6
11
- version: 0.8.0.rc6
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.0.rc7
5
+ prerelease: 6
12
6
  platform: ruby
13
- authors:
7
+ authors:
14
8
  - Aman Gupta
15
9
  - Jakub Stastny aka botanicus
16
10
  - Michael S. Klishin
17
11
  autorequire:
18
12
  bindir: bin
19
13
  cert_chain:
20
- date: 2011-05-06 00:00:00 +04:00
14
+ date: 2011-05-06 00:00:00.000000000 +04:00
21
15
  default_executable:
22
- dependencies:
23
- - !ruby/object:Gem::Dependency
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
24
18
  name: eventmachine
25
- prerelease: false
26
- requirement: &id001 !ruby/object:Gem::Requirement
19
+ requirement: &2156551420 !ruby/object:Gem::Requirement
27
20
  none: false
28
- requirements:
29
- - - ">="
30
- - !ruby/object:Gem::Version
31
- hash: 3
32
- segments:
33
- - 0
34
- version: "0"
21
+ requirements:
22
+ - - ! '>='
23
+ - !ruby/object:Gem::Version
24
+ version: '0'
35
25
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: amq-client
39
26
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
27
+ version_requirements: *2156551420
28
+ - !ruby/object:Gem::Dependency
29
+ name: amq-client
30
+ requirement: &2156550900 !ruby/object:Gem::Requirement
41
31
  none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- hash: 1369027924
46
- segments:
47
- - 0
48
- - 7
49
- - 0
50
- - alpha18
51
- version: 0.7.0.alpha18
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: 0.7.0.alpha20
52
36
  type: :runtime
53
- version_requirements: *id002
54
- description: Widely used, feature-rich asynchronous AMQP 0.9.1 client with batteries included
55
- email:
37
+ prerelease: false
38
+ version_requirements: *2156550900
39
+ description: Widely used, feature-rich asynchronous AMQP 0.9.1 client with batteries
40
+ included
41
+ email:
56
42
  - michael@novemberain.com
57
43
  - stastny@101ideas.cz
58
44
  executables: []
59
-
60
45
  extensions: []
61
-
62
- extra_rdoc_files:
46
+ extra_rdoc_files:
63
47
  - README.textile
64
48
  - docs/08Migration.textile
65
49
  - docs/Bindings.textile
@@ -75,7 +59,7 @@ extra_rdoc_files:
75
59
  - docs/RabbitMQVersions.textile
76
60
  - docs/Routing.textile
77
61
  - docs/VendorSpecificExtensions.textile
78
- files:
62
+ files:
79
63
  - .gitignore
80
64
  - .rspec
81
65
  - .travis.yml
@@ -144,6 +128,7 @@ files:
144
128
  - examples/legacy/primes-simple.rb
145
129
  - examples/legacy/primes.rb
146
130
  - examples/legacy/stocks.rb
131
+ - examples/publishing/publishing_and_immediately_stopping_event_loop.rb
147
132
  - examples/queues/automatic_binding_for_default_direct_exchange.rb
148
133
  - examples/queues/basic_get.rb
149
134
  - examples/queues/declare_a_queue_without_assignment.rb
@@ -219,38 +204,68 @@ files:
219
204
  has_rdoc: true
220
205
  homepage: http://github.com/ruby-amqp/amqp
221
206
  licenses: []
222
-
223
- post_install_message:
224
- rdoc_options:
207
+ post_install_message: ! "[\e[32mVersion 0.8.0\e[0m] [FEATURE] AMQP 0.9.1 support,
208
+ including tx.* operations class.\n[\e[32mVersion 0.8.0\e[0m] [API] Default authentication
209
+ handler now raises AMQP::PossibleAuthenticationFailureError\n[\e[32mVersion 0.8.0\e[0m]
210
+ [API] AMQP::Channel#initialize now takes 3rd (optional) options hash.\n[\e[32mVersion
211
+ 0.8.0\e[0m] [API] Broker connection class is now AMQP::Session.\n[\e[32mVersion
212
+ 0.8.0\e[0m] [API] AMQP::Error instance now may carry cause, an exception that caused
213
+ exception in question to be raised.\n[\e[32mVersion 0.8.0\e[0m] [API] When initial
214
+ TCP connection fails, default action is now to raise AMQP::TCPConnectionFailed.\n[\e[32mVersion
215
+ 0.8.0\e[0m] [API] AMQP::BasicClient#reconnect now takes 2nd optional argument, period
216
+ of waiting in seconds.\n[\e[32mVersion 0.8.0\e[0m] [FEATURE] Handlers for initial
217
+ connection failure, connection loss; channel-level exceptions handlers on Channel
218
+ instances.\n[\e[32mVersion 0.8.0\e[0m] [API] AMQP::Exchange#initialize now accepts
219
+ :arguments option that takes a hash.\n[\e[32mVersion 0.8.0\e[0m] [API] AMQP::Queue#initialize
220
+ now accepts :arguments option that takes a hash.\n[\e[32mVersion 0.8.0\e[0m] [API]
221
+ AMQP#Logger is deprecated. It will be removed before 1.0 release.\n[\e[32mVersion
222
+ 0.8.0\e[0m] [API] AMQP#fork is deprecated. It will be removed before 1.0 release.\n[\e[32mVersion
223
+ 0.8.0\e[0m] [API] AMQP::RPC is deprecated. It will be removed before 1.0 release.\n[\e[32mVersion
224
+ 0.8.0\e[0m] [FEATURE] Significant improvements to the documentation. From now on
225
+ lack of/poor documentation is considered a severe bug.\n[\e[32mVersion 0.8.0\e[0m]
226
+ [FEATURE] Support for RabbitMQ extensions to AMQP 0.9.1\n[\e[32mVersion 0.8.0\e[0m]
227
+ [API] AMQP::Exchange#publish now accepts (an optional) callback.\n[\e[32mVersion
228
+ 0.8.0\e[0m] [API] AMQP::Channel.new now accepts (an optional) callback.\n[\e[32mVersion
229
+ 0.8.0\e[0m] [API] AMQP::Header#ack now can acknowledge multiple deliveries\n[\e[32mVersion
230
+ 0.8.0\e[0m] [API] AMQP::Exchange#delete now takes (an optional) block that is called
231
+ when exchange.delete-ok response arrives.\n[\e[32mVersion 0.8.0\e[0m] [API] AMQP::Header
232
+ now implements #to_hash\n[\e[32mVersion 0.8.0\e[0m] [API] AMQP::Queue#pop block
233
+ now can take 1, 2 or 3 arguments.\n[\e[32mVersion 0.8.0\e[0m] [API] AMQP::Queue#purge
234
+ \ now takes an optional block which is called when queue.purge-ok response arrives.\n[\e[32mVersion
235
+ 0.8.0\e[0m] [API] AMQP::Queue#delete now takes an optional block which is called
236
+ when queue.delete-ok response arrives.\n[\e[32mVersion 0.8.0\e[0m] [API] AMQP::Queue#delete
237
+ now accepts :nowait option.\n[\e[32mVersion 0.8.0\e[0m] [API] AMQP::Queue#unbind
238
+ now takes an optional block which is called when queue.unbind-ok response arrives.\n[\e[32mVersion
239
+ 0.8.0\e[0m] [API] AMQP::Queue#unbind now accepts :routing_key as alias to :key.
240
+ we believe it is a good idea to use AMQP terms.\n[\e[32mVersion 0.8.0\e[0m] [API]
241
+ AMQP::Channel#prefetch now takes (an optional) 2nd parameter that specifies that
242
+ QoS settings should be applied to underlying connection, as well as optional callback.\n[\e[32mVersion
243
+ 0.8.0\e[0m] [API] AMQP::Channel#recover now takes (an optional) callback that is
244
+ called when basic.recover-ok is received.\n[\e[32mVersion 0.8.0\e[0m] [API] AMQP::Frame
245
+ is gone.\n[\e[32mVersion 0.8.0\e[0m] [API] AMQP::Buffer is gone. Serialization &
246
+ framing are now handled primarily by amq-protocol.\n[\e[32mVersion 0.8.0\e[0m] [API]
247
+ AMQP::Queue#publish is deprecated.\n[\e[32mVersion 0.8.0\e[0m] [API] Name argument
248
+ for AMQP::Queue.new and Channel#queue is optional.\n"
249
+ rdoc_options:
225
250
  - --include=examples --main README.textile
226
- require_paths:
251
+ require_paths:
227
252
  - lib
228
- required_ruby_version: !ruby/object:Gem::Requirement
253
+ required_ruby_version: !ruby/object:Gem::Requirement
229
254
  none: false
230
- requirements:
231
- - - ">="
232
- - !ruby/object:Gem::Version
233
- hash: 3
234
- segments:
235
- - 0
236
- version: "0"
237
- required_rubygems_version: !ruby/object:Gem::Requirement
255
+ requirements:
256
+ - - ! '>='
257
+ - !ruby/object:Gem::Version
258
+ version: '0'
259
+ required_rubygems_version: !ruby/object:Gem::Requirement
238
260
  none: false
239
- requirements:
240
- - - ">"
241
- - !ruby/object:Gem::Version
242
- hash: 25
243
- segments:
244
- - 1
245
- - 3
246
- - 1
261
+ requirements:
262
+ - - ! '>'
263
+ - !ruby/object:Gem::Version
247
264
  version: 1.3.1
248
265
  requirements: []
249
-
250
266
  rubyforge_project: amqp
251
- rubygems_version: 1.3.7
267
+ rubygems_version: 1.6.2
252
268
  signing_key:
253
269
  specification_version: 3
254
270
  summary: AMQP client implementation in Ruby/EventMachine.
255
271
  test_files: []
256
-