bunny 0.9.0.pre12 → 0.9.0.pre13

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9ee7de4a1d5a24771bf6fe5f7e070c6d6afd6340
4
- data.tar.gz: 3068de841ec8bbe3368b695866430a8f3859cf5a
3
+ metadata.gz: b138bcc7caf170e8104ab84dcf9dc4ae89387efa
4
+ data.tar.gz: e379d87d1c0fa62e5c84908f530d8160328873cf
5
5
  SHA512:
6
- metadata.gz: 8ebc06c578c1ef13ac197f44aac01f38ca469bccada8f500aaeb80a3b3e3320ce19588cdfce825b1b669e4eef48305b1d169bae22ffb94208ed25828fe4a8786
7
- data.tar.gz: 27bf9c563f423846c0cb3402779a043b2faf8b83a82099c8b5868934a8bff0b1b3164149b3b9c2a762a41b4f1d6b6fb66c6fcf560ba5b0ad9d10ee4b3520ff34
6
+ metadata.gz: f850913f5f76996a6f333ff5bc2a945506c99b1463999b2f912a1602d7f96ff293285d26beb48ddf99cba314f69c6910d38e23858408c11d39a18dc821583dff
7
+ data.tar.gz: a12db3df3ad28867e4af5268e5a8f623884649cddc2259ceef6fadbd716099fc7928712857ababe86ad4e336406ea0d3672f8b8d0dd2dab4547475feccf5a41b
@@ -1,3 +1,35 @@
1
+ ## Changes between Bunny 0.9.0.pre12 and 0.9.0.pre13
2
+
3
+ ### Channels Without Consumers Now Tear Down Consumer Pools
4
+
5
+ Channels without consumers left (when all consumers were cancelled)
6
+ will now tear down their consumer work thread pools, thus making
7
+ `HotBunnies::Queue#subscribe(:block => true)` calls unblock.
8
+
9
+ This is typically the desired behavior.
10
+
11
+ ### Consumer and Channel Available In Delivery Handlers
12
+
13
+ Delivery handlers registered via `Bunny::Queue#subscribe` now will have
14
+ access to the consumer and channel they are associated with via the
15
+ `delivery_info` argument:
16
+
17
+ ``` ruby
18
+ q.subscribe do |delivery_info, properties, payload|
19
+ delivery_info.consumer # => the consumer this delivery is for
20
+ delivery_info.consumer # => the channel this delivery is on
21
+ end
22
+ ```
23
+
24
+ This allows using `Bunny::Queue#subscribe` for one-off consumers
25
+ much easier, including when used with the `:block` option.
26
+
27
+ ### Bunny::Exchange#wait_for_confirms
28
+
29
+ `Bunny::Exchange#wait_for_confirms` is a convenience method on `Bunny::Exchange` that
30
+ delegates to the method with the same name on exchange's channel.
31
+
32
+
1
33
  ## Changes between Bunny 0.9.0.pre11 and 0.9.0.pre12
2
34
 
3
35
  ### Ruby 1.8 Compatibility Regression Fix
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require "rubygems"
5
+ require "bunny"
6
+
7
+ conn = Bunny.new
8
+ conn.start
9
+
10
+ ch = conn.create_channel
11
+ q = ch.queue("bunny.examples.hello_world", :auto_delete => true)
12
+
13
+ q.publish("Hello!", :routing_key => q.name)
14
+
15
+ # demonstrates a blocking consumer that needs to cancel itself
16
+ # in the message handler
17
+ q.subscribe(:block => true) do |delivery_info, properties, payload|
18
+ puts "Received #{payload}, cancelling"
19
+ delivery_info.consumer.cancel
20
+ end
21
+
22
+ sleep 1.0
23
+ conn.close
@@ -18,7 +18,7 @@ else
18
18
  end
19
19
 
20
20
  module Bunny
21
- # ## What are AMQP channels
21
+ # ## Channels in RabbitMQ
22
22
  #
23
23
  # To quote {http://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf AMQP 0.9.1 specification}:
24
24
  #
@@ -41,7 +41,7 @@ module Bunny
41
41
  #
42
42
  # ch = conn.create_channel
43
43
  #
44
- # This will automatically allocate channel id.
44
+ # This will automatically allocate a channel id.
45
45
  #
46
46
  # @example Instantiating
47
47
  #
@@ -806,9 +806,18 @@ module Bunny
806
806
  false,
807
807
  arguments))
808
808
 
809
- Bunny::Timer.timeout(read_write_timeout, ClientTimeout) do
810
- @last_basic_consume_ok = wait_on_continuations
809
+ begin
810
+ Bunny::Timer.timeout(read_write_timeout, ClientTimeout) do
811
+ @last_basic_consume_ok = wait_on_continuations
812
+ end
813
+ rescue Exception => e
814
+ # if basic.consume-ok never arrives, unregister the proactively
815
+ # registered consumer. MK.
816
+ unregister_consumer(@last_basic_consume_ok.consumer_tag)
817
+
818
+ raise e
811
819
  end
820
+
812
821
  # covers server-generated consumer tags
813
822
  add_consumer(queue_name, @last_basic_consume_ok.consumer_tag, no_ack, exclusive, arguments, &block)
814
823
 
@@ -827,6 +836,12 @@ module Bunny
827
836
  raise_if_no_longer_open!
828
837
  maybe_start_consumer_work_pool!
829
838
 
839
+ # helps avoid race condition between basic.consume-ok and basic.deliver if there are messages
840
+ # in the queue already. MK.
841
+ if consumer.consumer_tag && consumer.consumer_tag.strip != AMQ::Protocol::EMPTY_STRING
842
+ register_consumer(consumer.consumer_tag, consumer)
843
+ end
844
+
830
845
  @connection.send_frame(AMQ::Protocol::Basic::Consume.encode(@id,
831
846
  consumer.queue_name,
832
847
  consumer.consumer_tag,
@@ -836,15 +851,18 @@ module Bunny
836
851
  false,
837
852
  consumer.arguments))
838
853
 
839
- # helps avoid race condition between basic.consume-ok and basic.deliver if there are messages
840
- # in the queue already. MK.
841
- if consumer.consumer_tag && consumer.consumer_tag.strip != AMQ::Protocol::EMPTY_STRING
842
- register_consumer(consumer.consumer_tag, consumer)
843
- end
854
+ begin
855
+ Bunny::Timer.timeout(read_write_timeout, ClientTimeout) do
856
+ @last_basic_consume_ok = wait_on_continuations
857
+ end
858
+ rescue Exception => e
859
+ # if basic.consume-ok never arrives, unregister the proactively
860
+ # registered consumer. MK.
861
+ unregister_consumer(@last_basic_consume_ok.consumer_tag)
844
862
 
845
- Bunny::Timer.timeout(read_write_timeout, ClientTimeout) do
846
- @last_basic_consume_ok = wait_on_continuations
863
+ raise e
847
864
  end
865
+
848
866
  # covers server-generated consumer tags
849
867
  register_consumer(@last_basic_consume_ok.consumer_tag, consumer)
850
868
 
@@ -868,9 +886,17 @@ module Bunny
868
886
  @last_basic_cancel_ok = wait_on_continuations
869
887
  end
870
888
 
889
+ maybe_kill_consumer_work_pool! unless any_consumers?
890
+
871
891
  @last_basic_cancel_ok
872
892
  end
873
893
 
894
+ # @return [Boolean] true if there are consumers on this channel
895
+ # @api public
896
+ def any_consumers?
897
+ @consumer_mutex.synchronize { @consumers.any? }
898
+ end
899
+
874
900
  # @endgroup
875
901
 
876
902
 
@@ -1417,6 +1443,11 @@ module Bunny
1417
1443
  # @endgroup
1418
1444
 
1419
1445
 
1446
+ def to_s
1447
+ "#<#{self.class.name}:#{object_id} @id=#{self.number} @connection=#{@connection.to_s}>"
1448
+ end
1449
+
1450
+
1420
1451
  #
1421
1452
  # Implementation
1422
1453
  #
@@ -1428,6 +1459,13 @@ module Bunny
1428
1459
  end
1429
1460
  end
1430
1461
 
1462
+ # @private
1463
+ def unregister_consumer(consumer_tag)
1464
+ @consumer_mutex.synchronize do
1465
+ @consumers.delete(consumer_tag)
1466
+ end
1467
+ end
1468
+
1431
1469
  # @private
1432
1470
  def add_consumer(queue, consumer_tag, no_ack, exclusive, arguments, &block)
1433
1471
  @consumer_mutex.synchronize do
@@ -1475,7 +1513,7 @@ module Bunny
1475
1513
  @consumers.delete(method.consumer_tag)
1476
1514
  when AMQ::Protocol::Basic::CancelOk then
1477
1515
  @continuations.push(method)
1478
- @consumers.delete(method.consumer_tag)
1516
+ unregister_consumer(method.consumer_tag)
1479
1517
  when AMQ::Protocol::Tx::SelectOk, AMQ::Protocol::Tx::CommitOk, AMQ::Protocol::Tx::RollbackOk then
1480
1518
  @continuations.push(method)
1481
1519
  when AMQ::Protocol::Tx::SelectOk then
@@ -1525,7 +1563,7 @@ module Bunny
1525
1563
  consumer = @consumers[basic_deliver.consumer_tag]
1526
1564
  if consumer
1527
1565
  @work_pool.submit do
1528
- consumer.call(DeliveryInfo.new(basic_deliver), MessageProperties.new(properties), content)
1566
+ consumer.call(DeliveryInfo.new(basic_deliver, consumer, self), MessageProperties.new(properties), content)
1529
1567
  end
1530
1568
  else
1531
1569
  @logger.warn "No consumer for tag #{basic_deliver.consumer_tag} on channel #{@id}!"
@@ -83,6 +83,10 @@ module Bunny
83
83
  "#<#{self.class.name}:#{object_id} @channel_id=#{@channel.number} @queue=#{self.queue_name}> @consumer_tag=#{@consumer_tag} @exclusive=#{@exclusive} @no_ack=#{@no_ack}>"
84
84
  end
85
85
 
86
+ def to_s
87
+ "#<#{self.class.name}:#{object_id} @channel_id=#{@channel.number} @queue=#{self.queue_name}> @consumer_tag=#{@consumer_tag}>"
88
+ end
89
+
86
90
  #
87
91
  # Recovery
88
92
  #
@@ -14,15 +14,21 @@ module Bunny
14
14
  # API
15
15
  #
16
16
 
17
- def initialize(basic_deliver)
17
+ attr_reader :consumer, :channel
18
+
19
+ def initialize(basic_deliver, consumer, channel)
18
20
  @basic_deliver = basic_deliver
19
21
  @hash = {
20
22
  :consumer_tag => basic_deliver.consumer_tag,
21
23
  :delivery_tag => basic_deliver.delivery_tag,
22
24
  :redelivered => basic_deliver.redelivered,
23
25
  :exchange => basic_deliver.exchange,
24
- :routing_key => basic_deliver.routing_key
26
+ :routing_key => basic_deliver.routing_key,
27
+ :consumer => consumer,
28
+ :channel => channel
25
29
  }
30
+ @consumer = consumer
31
+ @channel = channel
26
32
  end
27
33
 
28
34
  def each(*args, &block)
@@ -70,7 +70,7 @@ module Bunny
70
70
  @username = username
71
71
  @vhost = vhost
72
72
 
73
- super("AMQP broker closed TCP connection before authentication succeeded: this usually means authentication failure due to misconfiguration or that RabbitMQ version does not support AMQP 0.9.1. Please check your configuration. Username: #{username}, vhost: #{vhost}, password length: #{password_length}")
73
+ super("RabbitMQ closed TCP connection before authentication succeeded: this usually means authentication failure due to misconfiguration or that RabbitMQ version does not support AMQP 0.9.1. Please check your configuration. Username: #{username}, vhost: #{vhost}, password length: #{password_length}")
74
74
  end # initialize(settings)
75
75
  end # PossibleAuthenticationFailureError
76
76
 
@@ -196,12 +196,23 @@ module Bunny
196
196
 
197
197
  # Defines a block that will handle returned messages
198
198
  # @see http://rubybunny.info/articles/exchanges.html
199
+ # @api public
199
200
  def on_return(&block)
200
201
  @on_return = block
201
202
 
202
203
  self
203
204
  end
204
205
 
206
+ # Waits until all outstanding publisher confirms on the channel
207
+ # arrive.
208
+ #
209
+ # This is a convenience method that delegates to {Bunny::Channel#wait_for_confirms}
210
+ #
211
+ # @api public
212
+ def wait_for_confirms
213
+ @channel.wait_for_confirms
214
+ end
215
+
205
216
  # @private
206
217
  def recover_from_network_failure
207
218
  # puts "Recovering exchange #{@name} from network failure"
@@ -648,7 +648,7 @@ module Bunny
648
648
  # @return [String]
649
649
  # @api public
650
650
  def to_s
651
- "Bunny::Session #{@user}@#{@host}:#{@port}, vhost=#{@vhost}"
651
+ "#<#{self.class.name}:#{object_id} #{@user}@#{@host}:#{@port}, vhost=#{@vhost}>"
652
652
  end
653
653
 
654
654
  protected
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Bunny
4
- VERSION = "0.9.0.pre12"
4
+ VERSION = "0.9.0.pre13"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bunny
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0.pre12
4
+ version: 0.9.0.pre13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Duncan
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2013-05-17 00:00:00.000000000 Z
15
+ date: 2013-05-30 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: amq-protocol
@@ -86,6 +86,7 @@ files:
86
86
  - examples/guides/getting_started/blabbr.rb
87
87
  - examples/guides/getting_started/hello_world.rb
88
88
  - examples/guides/getting_started/weathr.rb
89
+ - examples/guides/queues/one_off_consumer.rb
89
90
  - examples/guides/queues/redeliveries.rb
90
91
  - lib/bunny.rb
91
92
  - lib/bunny/authentication/credentials_encoder.rb