bunny 0.9.0.pre12 → 0.9.0.pre13

Sign up to get free protection for your applications and to get access to all the features.
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