Class: Bunny::Queue

Inherits:
Object
  • Object
show all
Defined in:
lib/bunny/queue.rb

Overview

Represents AMQP 0.9.1 queue.

Defined Under Namespace

Modules: Types, XArgs

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(channel, name = AMQ::Protocol::EMPTY_STRING, opts = {}) ⇒ Queue

Returns a new instance of Queue.

Parameters:

  • channel (Bunny::Channel)

    Channel this queue will use.

  • name (String) (defaults to: AMQ::Protocol::EMPTY_STRING)

    Queue name. Pass an empty string to make RabbitMQ generate a unique one.

  • opts (Hash) (defaults to: {})

    Queue properties

Options Hash (opts):

  • :durable (Boolean) — default: false

    Should this queue be durable?

  • :auto_delete (Boolean) — default: false

    Should this queue be automatically deleted when the last consumer disconnects?

  • :exclusive (Boolean) — default: false

    Should this queue be exclusive (only can be used by this connection, removed when the connection is closed)?

  • :type (String) — default: nil

    Type of the declared queue (classic, quorum, stream, delayed, or jms)

  • :arguments (Hash) — default: nil

    Additional optional arguments (typically used by RabbitMQ extensions and plugins)

See Also:



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/bunny/queue.rb', line 63

def initialize(channel, name = AMQ::Protocol::EMPTY_STRING, opts = {})
  # old Bunny versions pass a connection here. In that case,
  # we just use default channel from it. MK.
  @channel          = channel
  @name             = name
  @options          = self.class.add_default_options(name, opts)

  @durable          = @options[:durable]
  @exclusive        = @options[:exclusive]
  @server_named     = @name.empty?
  @auto_delete      = @options[:auto_delete]
  @type             = @options[:type]

  @arguments        = if @type and !@type.empty? then
    (@options[:arguments] || {}).merge({XArgs::QUEUE_TYPE => @type})
  else
    @options[:arguments]
  end
  verify_type!(@arguments)
  # reassigns updated and verified arguments because Bunny::Channel#declare_queue
  # accepts a map of options
  @options[:arguments] = @arguments

  @bindings         = Array.new

  @default_consumer = nil

  declare! unless opts[:no_declare]

  # for basic.deliver dispatch and such
  @channel.register_queue(self)
  # for topology recovery. A passive declaration does not own the queue,
  # so it must not overwrite what was recorded for it earlier
  @channel.record_queue(self) unless @options[:passive]
end

Instance Attribute Details

#channelBunny::Channel (readonly)

Returns Channel this queue uses.

Returns:



43
44
45
# File 'lib/bunny/queue.rb', line 43

def channel
  @channel
end

#nameString (readonly)

Returns Queue name.

Returns:

  • (String)

    Queue name



45
46
47
# File 'lib/bunny/queue.rb', line 45

def name
  @name
end

#optionsHash (readonly)

Returns Options this queue was created with.

Returns:

  • (Hash)

    Options this queue was created with



47
48
49
# File 'lib/bunny/queue.rb', line 47

def options
  @options
end

Class Method Details

.add_default_options(name, opts) ⇒ Object



399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# File 'lib/bunny/queue.rb', line 399

def self.add_default_options(name, opts)
  # :nowait is always false for Bunny
  h = { queue: name, nowait: false }.merge(opts)

  if name.empty?
    {
      passive:     false,
      durable:     false,
      exclusive:   false,
      auto_delete: false,
      arguments:   nil
    }.merge(h)
  else
    h
  end
end

.verify_type!(args0 = {}) ⇒ Object

Raises:

  • (ArgumentError)


378
379
380
381
382
383
384
# File 'lib/bunny/queue.rb', line 378

def self.verify_type!(args0 = {})
  # be extra defensive
  args = args0 || {}
  q_type = args["x-queue-type"] || args[:"x-queue-type"]
  raise ArgumentError,
    "unsupported queue type #{q_type.inspect}, supported ones: #{Types::KNOWN.join(', ')}" if (q_type and !Types.known?(q_type))
end

Instance Method Details

#argumentsHash

Returns Additional optional arguments (typically used by RabbitMQ extensions and plugins).

Returns:

  • (Hash)

    Additional optional arguments (typically used by RabbitMQ extensions and plugins)



129
130
131
# File 'lib/bunny/queue.rb', line 129

def arguments
  @arguments
end

#auto_delete?Boolean

Returns true if this queue was declared as automatically deleted (deleted as soon as last consumer unbinds).

Returns:

  • (Boolean)

    true if this queue was declared as automatically deleted (deleted as soon as last consumer unbinds).

See Also:



116
117
118
# File 'lib/bunny/queue.rb', line 116

def auto_delete?
  @auto_delete
end

#bind(exchange, opts = {}) ⇒ Object

Binds queue to an exchange

Parameters:

  • exchange (Bunny::Exchange, String)

    Exchange to bind to

  • opts (Hash) (defaults to: {})

    Binding properties

Options Hash (opts):

  • :routing_key (String)

    Routing key

  • :arguments (Hash) — default: {}

    Additional optional binding arguments

See Also:



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/bunny/queue.rb', line 160

def bind(exchange, opts = {})
  @channel.queue_bind(@name, exchange, opts)

  exchange_name = if exchange.is_a?(Bunny::Exchange)
                    exchange.name
                  else
                    exchange
                  end


  # store bindings for automatic recovery. We need to be very careful to
  # not cause an infinite rebinding loop here when we recover. MK.
  binding = { exchange: exchange_name, routing_key: (opts[:routing_key] || opts[:key]), arguments: opts[:arguments] }
  @bindings.push(binding) unless @bindings.include?(binding)

  self
end

#consumer_countInteger

Returns How many active consumers the queue has.

Returns:

  • (Integer)

    How many active consumers the queue has



373
374
375
376
# File 'lib/bunny/queue.rb', line 373

def consumer_count
  s = self.status
  s[:consumer_count]
end

#declare!Object



391
392
393
394
# File 'lib/bunny/queue.rb', line 391

def declare!
  queue_declare_ok = @channel.queue_declare(@name, @options)
  @name = queue_declare_ok.queue
end

#delete(opts = {}) ⇒ Object

Deletes the queue

Parameters:

  • opts (Hash) (defaults to: {})

    Options

Options Hash (opts):

  • if_unused (Boolean) — default: false

    Should this queue be deleted only if it has no consumers?

  • if_empty (Boolean) — default: false

    Should this queue be deleted only if it has no messages?

See Also:



342
343
344
345
346
# File 'lib/bunny/queue.rb', line 342

def delete(opts = {})
  @channel.delete_recorded_queue_named(self.name)
  @channel.deregister_queue(self)
  @channel.queue_delete(@name, opts)
end

#durable?Boolean

Returns true if this queue was declared as durable (will survive broker restart).

Returns:

  • (Boolean)

    true if this queue was declared as durable (will survive broker restart).

See Also:



102
103
104
# File 'lib/bunny/queue.rb', line 102

def durable?
  @durable
end

#exclusive?Boolean

Returns true if this queue was declared as exclusive (limited to just one consumer).

Returns:

  • (Boolean)

    true if this queue was declared as exclusive (limited to just one consumer)

See Also:



109
110
111
# File 'lib/bunny/queue.rb', line 109

def exclusive?
  @exclusive
end

#inspectObject



145
146
147
# File 'lib/bunny/queue.rb', line 145

def inspect
  to_s
end

#message_countInteger

Returns How many messages the queue has ready (e.g. not delivered but not unacknowledged).

Returns:

  • (Integer)

    How many messages the queue has ready (e.g. not delivered but not unacknowledged)



367
368
369
370
# File 'lib/bunny/queue.rb', line 367

def message_count
  s = self.status
  s[:message_count]
end

#pop(opts = { manual_ack: false }, &block) ⇒ Array Also known as: get

Returns Triple of delivery info, message properties and message content. If the queue is empty, all three will be nils.

Examples:

conn = Bunny.new
conn.start

ch   = conn.create_channel
q = ch.queue("test1")
x = ch.default_exchange
x.publish("Hello, everybody!", routing_key: 'test1')

delivery_info, properties, payload = q.pop

puts "This is the message: " + payload + "\n\n"
conn.close

Parameters:

  • opts (Hash) (defaults to: { manual_ack: false })

    Options

Options Hash (opts):

  • :ack (Boolean) — default: false

    [DEPRECATED] Use :manual_ack instead

  • :manual_ack (Boolean) — default: false

    Will the message be acknowledged manually?

Returns:

  • (Array)

    Triple of delivery info, message properties and message content. If the queue is empty, all three will be nils.

See Also:



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/bunny/queue.rb', line 291

def pop(opts = { manual_ack: false }, &block)
  unless opts[:ack].nil?
    warn "[DEPRECATION] `:ack` is deprecated.  Please use `:manual_ack` instead."
    opts[:manual_ack] = opts[:ack]
  end

  get_response, properties, content = @channel.basic_get(@name, opts)

  if block
    if properties
      di = GetResponse.new(get_response, @channel)
      mp = MessageProperties.new(properties)

      block.call(di, mp, content)
    else
      block.call(nil, nil, nil)
    end
  else
    if properties
      di = GetResponse.new(get_response, @channel)
      mp = MessageProperties.new(properties)
      [di, mp, content]
    else
      [nil, nil, nil]
    end
  end
end

#publish(payload, opts = {}) ⇒ Object

Publishes a message to the queue via default exchange. Takes the same arguments as Exchange#publish



326
327
328
329
330
# File 'lib/bunny/queue.rb', line 326

def publish(payload, opts = {})
  @channel.default_exchange.publish(payload, opts.merge(routing_key: @name))

  self
end

#purge(opts = {}) ⇒ Object

Purges a queue (removes all messages from it)



351
352
353
354
355
# File 'lib/bunny/queue.rb', line 351

def purge(opts = {})
  @channel.queue_purge(@name, opts)

  self
end

#server_named?Boolean

Returns true if this queue was declared as server named.

Returns:

  • (Boolean)

    true if this queue was declared as server named.

See Also:



123
124
125
# File 'lib/bunny/queue.rb', line 123

def server_named?
  @server_named
end

#statusHash

Returns A hash with information about the number of queue messages and consumers.

Returns:

  • (Hash)

    A hash with information about the number of queue messages and consumers

See Also:



360
361
362
363
364
# File 'lib/bunny/queue.rb', line 360

def status
  queue_declare_ok = @channel.queue_declare(@name, @options.merge(passive: true))
  { message_count: queue_declare_ok.message_count,
    consumer_count: queue_declare_ok.consumer_count }
end

#subscribe(opts = { consumer_tag: @channel.generate_consumer_tag, manual_ack: false, exclusive: false, block: false, on_cancellation: nil }, &block) ⇒ Object

Adds a consumer to the queue (subscribes for message deliveries).

Parameters:

  • opts (Hash) (defaults to: { consumer_tag: @channel.generate_consumer_tag, manual_ack: false, exclusive: false, block: false, on_cancellation: nil })

    Options

Options Hash (opts):

  • :ack (Boolean) — default: false

    [DEPRECATED] Use :manual_ack instead

  • :manual_ack (Boolean) — default: false

    Will this consumer use manual acknowledgements?

  • :exclusive (Boolean) — default: false

    Should this consumer be exclusive for this queue?

  • :on_cancellation (#call)

    Block to execute when this consumer is cancelled remotely (e.g. via the RabbitMQ Management plugin)

  • :consumer_tag (String)

    Unique consumer identifier. It is usually recommended to let Bunny generate it for you.

  • :arguments (Hash) — default: {}

    Additional (optional) arguments, typically used by RabbitMQ extensions

See Also:



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/bunny/queue.rb', line 217

def subscribe(opts = {
                consumer_tag:    @channel.generate_consumer_tag,
                manual_ack:      false,
                exclusive:       false,
                block:           false,
                on_cancellation: nil
              }, &block)

  unless opts[:ack].nil?
    warn "[DEPRECATION] `:ack` is deprecated.  Please use `:manual_ack` instead."
    opts[:manual_ack] = opts[:ack]
  end

  ctag       = opts.fetch(:consumer_tag, @channel.generate_consumer_tag)
  consumer   = Consumer.new(@channel,
                            self,
                            ctag,
                            !opts[:manual_ack],
                            opts[:exclusive],
                            opts[:arguments])

  consumer.on_delivery(&block)
  consumer.on_cancellation(&opts[:on_cancellation]) if opts[:on_cancellation]

  @channel.basic_consume_with(consumer)
  if opts[:block]
    # joins current thread with the consumers pool, will block
    # the current thread for as long as the consumer pool is active
    @channel.work_pool.join
  end

  consumer
end

#subscribe_with(consumer, opts = { block: false }) ⇒ Object

Adds a consumer object to the queue (subscribes for message deliveries).

Parameters:

  • consumer (Bunny::Consumer)

    a Consumer subclass that implements consumer interface

  • opts (Hash) (defaults to: { block: false })

    Options

Options Hash (opts):

  • block (Boolean) — default: false

    Should the call block calling thread?

See Also:



260
261
262
263
264
265
# File 'lib/bunny/queue.rb', line 260

def subscribe_with(consumer, opts = { block: false })
  @channel.basic_consume_with(consumer)

  @channel.work_pool.join if opts[:block]
  consumer
end

#to_sObject



140
141
142
143
# File 'lib/bunny/queue.rb', line 140

def to_s
  oid = ("0x%x" % (self.object_id << 1))
  "<#{self.class.name}:#{oid} @name=\"#{name}\" channel=#{@channel.to_s} @durable=#{@durable} @auto_delete=#{@auto_delete} @exclusive=#{@exclusive} @arguments=#{@arguments}>"
end

#unbind(exchange, opts = {}) ⇒ Object

Unbinds queue from an exchange

Parameters:

  • exchange (Bunny::Exchange, String)

    Exchange to unbind from

  • opts (Hash) (defaults to: {})

    Binding properties

Options Hash (opts):

  • :routing_key (String)

    Routing key

  • :arguments (Hash) — default: {}

    Additional optional binding arguments

See Also:



189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/bunny/queue.rb', line 189

def unbind(exchange, opts = {})
  @channel.queue_unbind(@name, exchange, opts)

  exchange_name = if exchange.is_a?(Bunny::Exchange)
                    exchange.name
                  else
                    exchange
                  end


  @bindings.delete_if { |b| b[:exchange] == exchange_name && b[:routing_key] == (opts[:routing_key] || opts[:key]) && b[:arguments] == opts[:arguments] }

  self
end

#update_name_to(value) ⇒ Object

Parameters:

  • value (String)


135
136
137
138
# File 'lib/bunny/queue.rb', line 135

def update_name_to(value)
  @name = value
  self
end