bunny 0.9.0.pre6 → 0.9.0.pre7

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.
@@ -8,6 +8,7 @@ module Bunny
8
8
  # API
9
9
  #
10
10
 
11
+ # @param [Integer] max_channel Max allowed channel id
11
12
  def initialize(max_channel = ((1 << 16) - 1))
12
13
  @int_allocator ||= AMQ::IntAllocator.new(1, max_channel)
13
14
 
@@ -29,7 +30,7 @@ module Bunny
29
30
 
30
31
  # Releases previously allocated channel id. This method is thread safe.
31
32
  #
32
- # @param [Fixnum] Channel id to release
33
+ # @param [Fixnum] i Channel id to release
33
34
  # @api public
34
35
  # @see ChannelManager#next_channel_id
35
36
  # @see ChannelManager#reset_channel_id_allocator
@@ -40,6 +41,14 @@ module Bunny
40
41
  end # self.release_channel_id(i)
41
42
 
42
43
 
44
+ # Returns true if given channel id has been previously allocated and not yet released.
45
+ # This method is thread safe.
46
+ #
47
+ # @param [Fixnum] i Channel id to check
48
+ # @return [Boolean] true if given channel id has been previously allocated and not yet released
49
+ # @api public
50
+ # @see ChannelManager#next_channel_id
51
+ # @see ChannelManager#release_channel_id
43
52
  def allocated_channel_id?(i)
44
53
  @channel_id_mutex.synchronize do
45
54
  @int_allocator.allocated?(i)
@@ -1,4 +1,13 @@
1
1
  module Bunny
2
+ # Base class that represents consumer interface. Subclasses of this class implement
3
+ # specific logic of handling consumer life cycle events. Note that when the only event
4
+ # you are interested in is message deliveries, it is recommended to just use
5
+ # {Bunny::Queue#subscribe} instead of subclassing this class.
6
+ #
7
+ # @see Bunny::Queue#subscribe
8
+ # @see Bunny::Queue#subscribe_with
9
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
10
+ # @api public
2
11
  class Consumer
3
12
 
4
13
  #
@@ -13,7 +22,15 @@ module Bunny
13
22
  attr_reader :exclusive
14
23
 
15
24
 
16
-
25
+ # @param [Bunny::Channel] channel Channel this consumer will use
26
+ # @param [Bunny::Queue,String] queue Queue messages will be consumed from
27
+ # @param [String] consumer_tag Consumer tag (unique identifier). Generally it is better to let Bunny generate one.
28
+ # Empty string means RabbitMQ will generate consumer tag.
29
+ # @param [Boolean] no_ack (false) If false, delivered messages will be automatically acknowledged.
30
+ # If true, manual acknowledgements will be necessary.
31
+ # @param [Boolean] exclusive (false) Should this consumer be exclusive?
32
+ # @param [Hash] arguments (nil) Optional arguments that may be used by RabbitMQ extensions, etc
33
+ # @api public
17
34
  def initialize(channel, queue, consumer_tag = channel.generate_consumer_tag, no_ack = true, exclusive = false, arguments = {})
18
35
  @channel = channel || raise(ArgumentError, "channel is nil")
19
36
  @queue = queue || raise(ArgumentError, "queue is nil")
@@ -23,34 +40,41 @@ module Bunny
23
40
  @no_ack = no_ack
24
41
  end
25
42
 
26
-
43
+ # Defines message delivery handler
44
+ # @api public
27
45
  def on_delivery(&block)
28
46
  @on_delivery = block
29
47
  self
30
48
  end
31
49
 
50
+ # Invokes message delivery handler
51
+ # @private
32
52
  def call(*args)
33
53
  @on_delivery.call(*args) if @on_delivery
34
54
  end
35
55
  alias handle_delivery call
36
56
 
57
+ # Defines consumer cancellation notification handler
58
+ #
59
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
60
+ # @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
61
+ # @api public
37
62
  def on_cancellation(&block)
38
63
  @on_cancellation = block
39
64
  self
40
65
  end
41
66
 
67
+ # Invokes consumer cancellation notification handler
68
+ # @private
42
69
  def handle_cancellation(basic_cancel)
43
70
  @on_cancellation.call(basic_cancel) if @on_cancellation
44
71
  end
45
72
 
46
- def queue_name
47
- if @queue.respond_to?(:name)
48
- @queue.name
49
- else
50
- @queue
51
- end
52
- end
53
-
73
+ # Cancels this consumer. Messages for this consumer will no longer be delivered. If the queue
74
+ # it was on is auto-deleted and this consumer was the last one, the queue will be deleted.
75
+ #
76
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
77
+ # @api public
54
78
  def cancel
55
79
  @channel.basic_cancel(@consumer_tag)
56
80
  end
@@ -63,8 +87,18 @@ module Bunny
63
87
  # Recovery
64
88
  #
65
89
 
90
+ # @private
66
91
  def recover_from_network_failure
67
92
  @channel.basic_consume_with(self)
68
93
  end
94
+
95
+ # @private
96
+ def queue_name
97
+ if @queue.respond_to?(:name)
98
+ @queue.name
99
+ else
100
+ @queue
101
+ end
102
+ end
69
103
  end
70
104
  end
@@ -136,4 +136,13 @@ module Bunny
136
136
 
137
137
  class UnexpectedFrame < ConnectionLevelException
138
138
  end
139
+
140
+ class NetworkErrorWrapper < StandardError
141
+ attr_reader :other
142
+
143
+ def initialize(other)
144
+ super(other.message)
145
+ @other = other
146
+ end
147
+ end
139
148
  end
@@ -1,6 +1,10 @@
1
1
  require "bunny/compatibility"
2
2
 
3
3
  module Bunny
4
+ # Represents AMQP 0.9.1 exchanges.
5
+ #
6
+ # @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
7
+ # @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
4
8
  class Exchange
5
9
 
6
10
  include Bunny::Compatibility
@@ -36,15 +40,16 @@ module Bunny
36
40
  # a routing key of "weather.usa.ca.sandiego" and there is a queue Q with this name,
37
41
  # that message will be routed to Q.
38
42
  #
39
- # @param [Bunny::Channel] channel Channel to use.
43
+ # @param [Bunny::Channel] channel_or_connection Channel to use. {Bunny::Session} instances
44
+ # are only supported for backwards compatibility.
40
45
  #
41
46
  # @example Publishing a messages to the tasks queue
42
47
  # channel = Bunny::Channel.new(connection)
43
48
  # tasks_queue = channel.queue("tasks")
44
49
  # Bunny::Exchange.default(channel).publish("make clean", routing_key => "tasks")
45
50
  #
46
- # @see Exchange
47
- # @see http://files.travis-ci.org/docs/amqp/0.9.1/AMQP091Specification.pdf AMQP 0.9.1 specification (Section 2.1.2.4)
51
+ # @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
52
+ # @see http://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf AMQP 0.9.1 specification (Section 2.1.2.4)
48
53
  # @note Do not confuse default exchange with amq.direct: amq.direct is a pre-defined direct
49
54
  # exchange that doesn't have any special routing semantics.
50
55
  # @return [Exchange] An instance that corresponds to the default exchange (of type direct).
@@ -53,7 +58,23 @@ module Bunny
53
58
  self.new(channel_from(channel_or_connection), :direct, AMQ::Protocol::EMPTY_STRING, :no_declare => true)
54
59
  end
55
60
 
56
-
61
+ # @param [Bunny::Channel] channel_or_connection Channel this exchange will use. {Bunny::Session} instances are supported only for
62
+ # backwards compatibility with 0.8.
63
+ # @param [Symbol,String] type Exchange type
64
+ # @param [String] name Exchange name
65
+ # @param [Hash] opts Exchange properties
66
+ #
67
+ # @option opts [Boolean] :durable (false) Should this exchange be durable?
68
+ # @option opts [Boolean] :auto_delete (false) Should this exchange be automatically deleted when it is no longer used?
69
+ # @option opts [Boolean] :arguments ({}) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
70
+ #
71
+ # @see Bunny::Channel#topic
72
+ # @see Bunny::Channel#fanout
73
+ # @see Bunny::Channel#direct
74
+ # @see Bunny::Channel#headers
75
+ # @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
76
+ # @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
77
+ # @api public
57
78
  def initialize(channel_or_connection, type, name, opts = {})
58
79
  # old Bunny versions pass a connection here. In that case,
59
80
  # we just use default channel from it. MK.
@@ -66,7 +87,7 @@ module Bunny
66
87
  @auto_delete = @options[:auto_delete]
67
88
  @arguments = @options[:arguments]
68
89
 
69
- declare! unless opts[:no_declare] || (@name =~ /^amq\.(direct|fanout|topic|match|headers)/) || (@name == AMQ::Protocol::EMPTY_STRING)
90
+ declare! unless opts[:no_declare] || predeclared? || (@name == AMQ::Protocol::EMPTY_STRING)
70
91
 
71
92
  @channel.register_exchange(self)
72
93
  end
@@ -83,15 +104,36 @@ module Bunny
83
104
  @auto_delete
84
105
  end # auto_delete?
85
106
 
107
+ # @return [Hash] Additional optional arguments (typically used by RabbitMQ extensions and plugins)
108
+ # @api public
86
109
  def arguments
87
110
  @arguments
88
111
  end
89
112
 
90
- def predeclared?
91
- @name == AMQ::Protocol::EMPTY_STRING || (@name =~ /^amq\.(direct|fanout|topic|match|headers)/)
92
- end
93
-
94
113
 
114
+ # Publishes a message
115
+ #
116
+ # @param [String] payload Message payload. It will never be modified by Bunny or RabbitMQ in any way.
117
+ # @param [Hash] opts Message properties (metadata) and delivery settings
118
+ #
119
+ # @option opts [String] :routing_key Routing key
120
+ # @option opts [Boolean] :persistent Should the message be persisted to disk?
121
+ # @option opts [Boolean] :mandatory Should the message be returned if it cannot be routed to any queue?
122
+ # @option opts [Integer] :timestamp A timestamp associated with this message
123
+ # @option opts [Integer] :expiration Expiration time after which the message will be deleted
124
+ # @option opts [String] :type Message type, e.g. what type of event or command this message represents. Can be any string
125
+ # @option opts [String] :reply_to Queue name other apps should send the response to
126
+ # @option opts [String] :content_type Message content type (e.g. application/json)
127
+ # @option opts [String] :content_encoding Message content encoding (e.g. gzip)
128
+ # @option opts [String] :correlation_id Message correlated to this one, e.g. what request this message is a reply for
129
+ # @option opts [Integer] :priority Message priority, 0 to 9. Not used by RabbitMQ, only applications
130
+ # @option opts [String] :message_id Any message identifier
131
+ # @option opts [String] :user_id Optional user ID. Verified by RabbitMQ against the actual connection username
132
+ # @option opts [String] :app_id Optional application ID
133
+ #
134
+ # @return [Bunny::Exchange] Self
135
+ # @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
136
+ # @api public
95
137
  def publish(payload, opts = {})
96
138
  @channel.basic_publish(payload, self.name, (opts.delete(:routing_key) || opts.delete(:key)), opts)
97
139
 
@@ -100,32 +142,67 @@ module Bunny
100
142
 
101
143
 
102
144
  # Deletes the exchange unless it is a default exchange
145
+ #
146
+ # @param [Hash] opts Options
147
+ #
148
+ # @option opts [Boolean] if_unused (false) Should this exchange be deleted only if it is no longer used
149
+ #
150
+ # @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
103
151
  # @api public
104
152
  def delete(opts = {})
105
153
  @channel.deregister_exchange(self)
106
154
  @channel.exchange_delete(@name, opts) unless predeclared?
107
155
  end
108
156
 
109
-
157
+ # Binds an exchange to another (source) exchange using exchange.bind AMQP 0.9.1 extension
158
+ # that RabbitMQ provides.
159
+ #
160
+ # @param [String] source Source exchange name
161
+ # @param [Hash] opts Options
162
+ #
163
+ # @option opts [String] routing_key (nil) Routing key used for binding
164
+ # @option opts [Hash] arguments ({}) Optional arguments
165
+ #
166
+ # @return [Bunny::Exchange] Self
167
+ # @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
168
+ # @see http://rubybunny.info/articles/bindings.html Bindings guide
169
+ # @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
170
+ # @api public
110
171
  def bind(source, opts = {})
111
172
  @channel.exchange_bind(source, self, opts)
112
173
 
113
174
  self
114
175
  end
115
176
 
177
+ # Unbinds an exchange from another (source) exchange using exchange.unbind AMQP 0.9.1 extension
178
+ # that RabbitMQ provides.
179
+ #
180
+ # @param [String] source Source exchange name
181
+ # @param [Hash] opts Options
182
+ #
183
+ # @option opts [String] routing_key (nil) Routing key used for binding
184
+ # @option opts [Hash] arguments ({}) Optional arguments
185
+ #
186
+ # @return [Bunny::Exchange] Self
187
+ # @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
188
+ # @see http://rubybunny.info/articles/bindings.html Bindings guide
189
+ # @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
190
+ # @api public
116
191
  def unbind(source, opts = {})
117
192
  @channel.exchange_unbind(source, self, opts)
118
193
 
119
194
  self
120
195
  end
121
196
 
122
-
197
+ # Defines a block that will handle returned messages
198
+ # @see http://rubybunny.info/articles/exchanges.html
123
199
  def on_return(&block)
124
200
  @on_return = block
125
201
 
126
202
  self
127
203
  end
128
204
 
205
+ # @private
129
206
  def recover_from_network_failure
130
207
  # puts "Recovering exchange #{@name} from network failure"
131
208
  declare! unless predefined?
@@ -136,6 +213,7 @@ module Bunny
136
213
  # Implementation
137
214
  #
138
215
 
216
+ # @private
139
217
  def handle_return(basic_return, properties, content)
140
218
  if @on_return
141
219
  @on_return.call(basic_return, properties, content)
@@ -146,8 +224,9 @@ module Bunny
146
224
 
147
225
  # @return [Boolean] true if this exchange is a pre-defined one (amq.direct, amq.fanout, amq.match and so on)
148
226
  def predefined?
149
- @name && ((@name == AMQ::Protocol::EMPTY_STRING) || !!(@name =~ /^amq\./i))
227
+ (@name == AMQ::Protocol::EMPTY_STRING) || !!(@name =~ /^amq\.(direct|fanout|topic|headers|match)/i)
150
228
  end # predefined?
229
+ alias predeclared? predefined?
151
230
 
152
231
  protected
153
232
 
@@ -16,6 +16,7 @@ module Bunny
16
16
 
17
17
  def start
18
18
  @thread = Thread.new(&method(:run_loop))
19
+ @thread.abort_on_exception = true
19
20
  end
20
21
 
21
22
  def resume
@@ -27,29 +28,7 @@ module Bunny
27
28
  loop do
28
29
  begin
29
30
  break if @stopping || @network_is_down
30
-
31
- frame = @transport.read_next_frame
32
- @session.signal_activity!
33
-
34
- next if frame.is_a?(AMQ::Protocol::HeartbeatFrame)
35
-
36
- if !frame.final? || frame.method_class.has_content?
37
- header = @transport.read_next_frame
38
- content = ''
39
-
40
- if header.body_size > 0
41
- loop do
42
- body_frame = @transport.read_next_frame
43
- content << body_frame.decode_payload
44
-
45
- break if content.bytesize >= header.body_size
46
- end
47
- end
48
-
49
- @session.handle_frameset(frame.channel, [frame.decode_payload, header.decode_payload, content])
50
- else
51
- @session.handle_frame(frame.channel, frame.decode_payload)
52
- end
31
+ run_once
53
32
  rescue Timeout::Error => te
54
33
  # given that the server may be pushing data to us, timeout detection/handling
55
34
  # should happen per operation and not in this loop
@@ -67,6 +46,31 @@ module Bunny
67
46
  end
68
47
  end
69
48
 
49
+ def run_once
50
+ frame = @transport.read_next_frame
51
+ @session.signal_activity!
52
+
53
+ return if frame.is_a?(AMQ::Protocol::HeartbeatFrame)
54
+
55
+ if !frame.final? || frame.method_class.has_content?
56
+ header = @transport.read_next_frame
57
+ content = ''
58
+
59
+ if header.body_size > 0
60
+ loop do
61
+ body_frame = @transport.read_next_frame
62
+ content << body_frame.decode_payload
63
+
64
+ break if content.bytesize >= header.body_size
65
+ end
66
+ end
67
+
68
+ @session.handle_frameset(frame.channel, [frame.decode_payload, header.decode_payload, content])
69
+ else
70
+ @session.handle_frame(frame.channel, frame.decode_payload)
71
+ end
72
+ end
73
+
70
74
  def stop
71
75
  @stopping = true
72
76
  end
@@ -1,6 +1,10 @@
1
1
  require "bunny/compatibility"
2
2
 
3
3
  module Bunny
4
+ # Represents AMQP 0.9.1 queue.
5
+ #
6
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
7
+ # @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
4
8
  class Queue
5
9
 
6
10
  include Bunny::Compatibility
@@ -10,8 +14,27 @@ module Bunny
10
14
  # API
11
15
  #
12
16
 
13
- attr_reader :channel, :name, :options
14
-
17
+ # @return [Bunny::Channel] Channel this queue uses
18
+ attr_reader :channel
19
+ # @return [String] Queue name
20
+ attr_reader :name
21
+ # @return [Hash] Options this queue was created with
22
+ attr_reader :options
23
+
24
+ # @param [Bunny::Channel] channel_or_connection Channel this queue will use. {Bunny::Session} instances are supported only for
25
+ # backwards compatibility with 0.8.
26
+ # @param [String] name Queue name. Pass an empty string to make RabbitMQ generate a unique one.
27
+ # @param [Hash] opts Queue properties
28
+ #
29
+ # @option opts [Boolean] :durable (false) Should this queue be durable?
30
+ # @option opts [Boolean] :auto_delete (false) Should this queue be automatically deleted when the last consumer disconnects?
31
+ # @option opts [Boolean] :exclusive (false) Should this queue be exclusive (only can be used by this connection, removed when the connection is closed)?
32
+ # @option opts [Boolean] :arguments ({}) Additional optional arguments (typically used by RabbitMQ extensions and plugins)
33
+ #
34
+ # @see Bunny::Channel#queue
35
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
36
+ # @see http://rubybunny.info/articles/extensions.html RabbitMQ Extensions guide
37
+ # @api public
15
38
  def initialize(channel_or_connection, name = AMQ::Protocol::EMPTY_STRING, opts = {})
16
39
  # old Bunny versions pass a connection here. In that case,
17
40
  # we just use default channel from it. MK.
@@ -37,33 +60,50 @@ module Bunny
37
60
 
38
61
  # @return [Boolean] true if this queue was declared as durable (will survive broker restart).
39
62
  # @api public
63
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
40
64
  def durable?
41
65
  @durable
42
66
  end # durable?
43
67
 
44
68
  # @return [Boolean] true if this queue was declared as exclusive (limited to just one consumer)
45
69
  # @api public
70
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
46
71
  def exclusive?
47
72
  @exclusive
48
73
  end # exclusive?
49
74
 
50
75
  # @return [Boolean] true if this queue was declared as automatically deleted (deleted as soon as last consumer unbinds).
51
76
  # @api public
77
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
52
78
  def auto_delete?
53
79
  @auto_delete
54
80
  end # auto_delete?
55
81
 
56
82
  # @return [Boolean] true if this queue was declared as server named.
57
83
  # @api public
84
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
58
85
  def server_named?
59
86
  @server_named
60
87
  end # server_named?
61
88
 
89
+ # @return [Hash] Additional optional arguments (typically used by RabbitMQ extensions and plugins)
90
+ # @api public
62
91
  def arguments
63
92
  @arguments
64
93
  end
65
94
 
66
95
 
96
+ # Binds queue to an exchange
97
+ #
98
+ # @param [Bunny::Exchange,String] exchange Exchange to bind to
99
+ # @param [Hash] opts Binding properties
100
+ #
101
+ # @option opts [String] :routing_key Routing key
102
+ # @option opts [Hash] :arguments ({}) Additional optional binding arguments
103
+ #
104
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
105
+ # @see http://rubybunny.info/articles/bindings.html Bindings guide
106
+ # @api public
67
107
  def bind(exchange, opts = {})
68
108
  @channel.queue_bind(@name, exchange, opts)
69
109
 
@@ -82,6 +122,17 @@ module Bunny
82
122
  self
83
123
  end
84
124
 
125
+ # Unbinds queue from an exchange
126
+ #
127
+ # @param [Bunny::Exchange,String] exchange Exchange to unbind from
128
+ # @param [Hash] opts Binding properties
129
+ #
130
+ # @option opts [String] :routing_key Routing key
131
+ # @option opts [Hash] :arguments ({}) Additional optional binding arguments
132
+ #
133
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
134
+ # @see http://rubybunny.info/articles/bindings.html Bindings guide
135
+ # @api public
85
136
  def unbind(exchange, opts = {})
86
137
  @channel.queue_unbind(@name, exchange, opts)
87
138
 
@@ -97,6 +148,19 @@ module Bunny
97
148
  self
98
149
  end
99
150
 
151
+ # Adds a consumer to the queue (subscribes for message deliveries).
152
+ #
153
+ # @param [Hash] opts Options
154
+ #
155
+ # @option opts [Boolean] :manual_ack (false) Will this consumer use manual acknowledgements?
156
+ # @option opts [Boolean] :exclusive (false) Should this consumer be exclusive for this queue?
157
+ # @option opts [Boolean] :block (false) Should the call block calling thread?
158
+ # @option opts [#call] :on_cancellation Block to execute when this consumer is cancelled remotely (e.g. via the RabbitMQ Management plugin)
159
+ # @option opts [String] :consumer_tag Unique consumer identifier. It is usually recommended to let Bunny generate it for you.
160
+ # @option opts [Hash] :arguments ({}) Additional (optional) arguments, typically used by RabbitMQ extensions
161
+ #
162
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
163
+ # @api public
100
164
  def subscribe(opts = {
101
165
  :consumer_tag => @channel.generate_consumer_tag,
102
166
  :ack => false,
@@ -109,10 +173,10 @@ module Bunny
109
173
  consumer = Consumer.new(@channel,
110
174
  self,
111
175
  ctag,
112
- !opts[:ack],
176
+ !(opts[:ack] || opts[:manual_ack]),
113
177
  opts[:exclusive],
114
178
  opts[:arguments])
115
- puts "Added consumer #{ctag} on queue #{@name}"
179
+
116
180
  consumer.on_delivery(&block)
117
181
  consumer.on_cancellation(&opts[:on_cancellation]) if opts[:on_cancellation]
118
182
 
@@ -126,6 +190,15 @@ module Bunny
126
190
  consumer
127
191
  end
128
192
 
193
+ # Adds a consumer object to the queue (subscribes for message deliveries).
194
+ #
195
+ # @param [Bunny::Consumer] consumer a {Bunny::Consumer} subclass that implements consumer interface
196
+ # @param [Hash] opts Options
197
+ #
198
+ # @option opts [Boolean] block (false) Should the call block calling thread?
199
+ #
200
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
201
+ # @api public
129
202
  def subscribe_with(consumer, opts = {:block => false})
130
203
  @channel.basic_consume_with(consumer)
131
204
 
@@ -133,6 +206,29 @@ module Bunny
133
206
  consumer
134
207
  end
135
208
 
209
+ # @param [Hash] opts Options
210
+ #
211
+ # @option opts [Boolean] block (false) Should the call block calling thread?
212
+ #
213
+ # @return [Array] Triple of delivery info, message properties and message content.
214
+ # If the queue is empty, all three will be nils.
215
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
216
+ # @see Bunny::Queue#subscribe
217
+ # @api public
218
+ #
219
+ # @example
220
+ # conn = Bunny.new
221
+ # conn.start
222
+ #
223
+ # ch = conn.create_channel
224
+ # q = ch.queue("test1")
225
+ # x = ch.default_exchange
226
+ # x.publish("Hello, everybody!", :routing_key => 'test1')
227
+ #
228
+ # delivery_info, properties, payload = q.pop
229
+ #
230
+ # puts "This is the message: " + payload + "\n\n"
231
+ # conn.close
136
232
  def pop(opts = {:ack => false}, &block)
137
233
  delivery_info, properties, content = @channel.basic_get(@name, opts)
138
234
 
@@ -144,6 +240,10 @@ module Bunny
144
240
  end
145
241
  alias get pop
146
242
 
243
+ # Version of {Bunny::Queue#pop} that returns data in legacy format
244
+ # (as a hash).
245
+ # @return [Hash]
246
+ # @deprecated
147
247
  def pop_as_hash(opts = {:ack => false}, &block)
148
248
  delivery_info, properties, content = @channel.basic_get(@name, opts)
149
249
 
@@ -156,10 +256,12 @@ module Bunny
156
256
  end
157
257
  end
158
258
 
159
- # Publishes a message to the queue via default exchange.
259
+ # Publishes a message to the queue via default exchange. Takes the same arguments
260
+ # as {Bunny::Exchange#publish}
160
261
  #
161
262
  # @see Bunny::Exchange#publish
162
263
  # @see Bunny::Channel#default_exchange
264
+ # @see http://rubybunny.info/articles/exchanges.html Exchanges and Publishing guide
163
265
  def publish(payload, opts = {})
164
266
  @channel.default_exchange.publish(payload, opts.merge(:routing_key => @name))
165
267
 
@@ -168,29 +270,44 @@ module Bunny
168
270
 
169
271
 
170
272
  # Deletes the queue
273
+ #
274
+ # @param [Hash] opts Options
275
+ #
276
+ # @option opts [Boolean] if_unused (false) Should this queue be deleted only if it has no consumers?
277
+ # @option opts [Boolean] if_empty (false) Should this queue be deleted only if it has no messages?
278
+ #
279
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
171
280
  # @api public
172
281
  def delete(opts = {})
173
282
  @channel.deregister_queue(self)
174
283
  @channel.queue_delete(@name, opts)
175
284
  end
176
285
 
286
+ # Purges a queue (removes all messages from it)
287
+ # @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
288
+ # @api public
177
289
  def purge(opts = {})
178
290
  @channel.queue_purge(@name, opts)
179
291
 
180
292
  self
181
293
  end
182
294
 
295
+ # @return [Hash] A hash with information about the number of queue messages and consumers
296
+ # @see #message_count
297
+ # @see #consumer_count
183
298
  def status
184
299
  queue_declare_ok = @channel.queue_declare(@name, @options.merge(:passive => true))
185
300
  {:message_count => queue_declare_ok.message_count,
186
301
  :consumer_count => queue_declare_ok.consumer_count}
187
302
  end
188
303
 
304
+ # @return [Integer] How many messages the queue has ready (e.g. not delivered but not unacknowledged)
189
305
  def message_count
190
306
  s = self.status
191
307
  s[:message_count]
192
308
  end
193
309
 
310
+ # @return [Integer] How many active consumers the queue has
194
311
  def consumer_count
195
312
  s = self.status
196
313
  s[:consumer_count]
@@ -200,9 +317,8 @@ module Bunny
200
317
  # Recovery
201
318
  #
202
319
 
320
+ # @private
203
321
  def recover_from_network_failure
204
- # puts "Recovering queue #{@name} from network failure"
205
-
206
322
  if self.server_named?
207
323
  old_name = @name.dup
208
324
  @name = AMQ::Protocol::EMPTY_STRING
@@ -210,17 +326,21 @@ module Bunny
210
326
  @channel.deregister_queue_named(old_name)
211
327
  end
212
328
 
213
- declare!
329
+ # puts "Recovering queue #{@name}"
214
330
  begin
331
+ declare!
332
+
215
333
  @channel.register_queue(self)
216
334
  rescue Exception => e
217
- puts "Caught #{e.inspect} while registering #{@name}!"
335
+ puts "Caught #{e.inspect} while redeclaring and registering #{@name}!"
218
336
  end
219
337
  recover_bindings
220
338
  end
221
339
 
340
+ # @private
222
341
  def recover_bindings
223
342
  @bindings.each do |b|
343
+ # puts "Recovering binding #{b.inspect}"
224
344
  self.bind(b[:exchange], b)
225
345
  end
226
346
  end