bunny 0.9.0.pre6 → 0.9.0.pre7

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