Rabbit v0.5.1 Rabbit.Consumer behaviour View Source

A RabbitMQ consumer process.

This wraps around the standard AMQP.Channel. It provides the following benefits:

  • Durability during connection and channel failures through use of expotential backoff.
  • Easy runtime setup through the init/2 and handle_setup/2 callbacks.
  • Automatic acknowledgements based on the return value of the handle_message/1 callback.
  • Ability to handle exceptions through the handle_error/1 callback.
  • Each message is executed within its own supervised task.
  • Automatic payload decoding based on available serializers and message content type.

Example

# This is a connection
defmodule MyConnection do
  use Rabbit.Connection

  def start_link(opts \\ []) do
    Rabbit.Connection.start_link(__MODULE__, opts, name: __MODULE__)
  end

  # Callbacks

  @impl Rabbit.Connection
  def init(:connection, opts) do
    # Perform any runtime configuration
    {:ok, opts}
  end
end

# This is a consumer
defmodule MyConsumer do
  use Rabbit.Consumer

  def start_link(opts \\ []) do
    Rabbit.Consumer.start_link(__MODULE__, opts, name: __MODULE__)
  end

  # Callbacks

  @impl Rabbit.Consumer
  def init(_type, opts) do
    # Perform any runtime configuration
    {:ok, opts}
  end

  @impl Rabbit.Consumer
  def handle_setup(channel, queue) do
    # Perform exchange or queue setup
    AMQP.Queue.declare(channel, queue)

    :ok
  end

  @impl Rabbit.Consumer
  def handle_message(message) do
    # Handle consumed messages
    {:ack, message}
  end

  @impl Rabbit.Consumer
  def handle_error(message) do
    # Handle errors that occur within handle_message/1
    {:nack, message}
  end
end

# Start the connection
MyConnection.start_link()

# Start the consumer
MyConsumer.start_link(connection: MyConnection, queue: "my_queue", prefetch_count: 20)

Serializers

When a message is consumed, its content type is compared to the list of available serializers. If a serializer matches the content type, the message will be automatically decoded.

You can find out more about serializers at Rabbit.Serializer.

Link to this section Summary

Functions

Awknowledges a message from its delivery tag.

Negative awknowledges a message from its delivery tag.

Rejects a message from its delivery tag.

Stops a consumer process.

Callbacks

A callback executed to handle message exceptions.

A callback executed to handle message consumption.

A callback executed after the channel is open, but before consumption.

A callback executed when the consumer is started.

Link to this section Types

Link to this type

action_options() View Source
action_options() :: [multiple: boolean(), requeue: boolean()]

Link to this type

delivery_tag() View Source
delivery_tag() :: non_neg_integer()

Link to this type

option() View Source
option() ::
  {:connection, Rabbit.Connection.t()}
  | {:queue, String.t()}
  | {:prefetch_count, non_neg_integer()}
  | {:prefetch_size, non_neg_integer()}
  | {:consumer_tag, String.t()}
  | {:no_local, boolean()}
  | {:no_ack, boolean()}
  | {:exclusive, boolean()}
  | {:no_wait, boolean()}
  | {:arguments, Keyword.t()}

Link to this type

options() View Source
options() :: [option()]

Link to this section Functions

Link to this function

ack(consumer, delivery_tag, opts \\ []) View Source

Awknowledges a message from its delivery tag.

Options

  • :multiple - If true, all messages up to the one specified by delivery_tag are considered acknowledged by the server.
Link to this function

nack(consumer, delivery_tag, opts \\ []) View Source

Negative awknowledges a message from its delivery tag.

Options

  • :multiple - If true, all messages up to the one specified by delivery_tag are considered acknowledged by the server.
  • :requeue - If true, the message will be returned to the queue and redelivered to the next available consumer.
Link to this function

reject(consumer, delivery_tag, opts \\ []) View Source

Rejects a message from its delivery tag.

Options

  • :requeue - If true, the message will be returned to the queue and redelivered to the next available consumer.
Link to this function

start_link(module, opts \\ [], server_opts \\ []) View Source

Starts a consumer process.

Options

  • :connection - A Rabbit.Connection process.
  • :queue - The queue to consume messages from.
  • :prefetch_count - The basic unit of concurrency for a given consumer - defaults to 0.
  • :prefetch_size - The prefetch window size in octets - defaults to 0, meaning no specific limit.
  • :consumer_tag - The identifier of the consumer. If empty, one will be generared by the server.
  • :no_local - A boolean representing whether messages should not be sent to the same connection that published them - defaults to false.
  • :no_ack - A boolean representing whether acknowledgements are not required for messages - defaults to false.
  • :exclusive - A boolean representing whether only this consumer can access the queue - defaults to false.
  • :no_wait - A boolean representing whether the server should not respond to methods - defaults to false.
  • :arguments - A set of arguments for the consume.

Server Options

You can also provide server options - which are simply the same ones available for GenServer.options/0.

Stops a consumer process.

Link to this section Callbacks

Link to this callback

handle_error(message) View Source
handle_error(message :: Rabbit.Message.t()) ::
  {:ack, Rabbit.Message.t()}
  | {:ack, Rabbit.Message.t(), action_options()}
  | {:nack, Rabbit.Message.t()}
  | {:nack, Rabbit.Message.t(), action_options()}
  | {:reject, Rabbit.Message.t()}
  | {:reject, Rabbit.Message.t(), action_options()}
  | any()

A callback executed to handle message exceptions.

If the original handle_message/1 callback raises an error, this callback will be called with the message - but with the :error_reason and :error_stack fields filled.

You may choose to return the same values as handle_message/1.

Link to this callback

handle_message(message) View Source
handle_message(message :: Rabbit.Message.t()) ::
  {:ack, Rabbit.Message.t()}
  | {:ack, Rabbit.Message.t(), action_options()}
  | {:nack, Rabbit.Message.t()}
  | {:nack, Rabbit.Message.t(), action_options()}
  | {:reject, Rabbit.Message.t()}
  | {:reject, Rabbit.Message.t(), action_options()}
  | any()

A callback executed to handle message consumption.

The callback is called with a Rabbit.Message struct. You may find more information about the message structure within its own documentation. The message may be automatically decoded based on the content type and available serializers.

You may choose to ack, nack, or reject the message based on the return value.

  • {:ack, message} - will awknowledge the message.
  • {:ack, message, options} - will awknowledge the message with options.
  • {:nack, message} - will negative awknowledge the message.
  • {:nack, message, options} - will negative awknowledge the message with options.
  • {:reject, message} - will reject the message.
  • {:reject, message, options} - will reject the message with options.

If you dont return one of these values - nothing will be done.

Link to this callback

handle_setup(channel, queue) View Source
handle_setup(channel :: AMQP.Channel.t(), queue :: String.t()) :: :ok

A callback executed after the channel is open, but before consumption.

The callback is called with an AMQP.Channel, as well as the queue that will be consumed. At the most basic, you will most likely want to declare the queue to ensure its available. This will be entirely application dependent though.

def after_connect(channel, queue) do
  AMQP.Queue.declare(channel, queue)

  :ok
end

The callback must return an :ok atom - otherise it will be marked as failed, and the consumer will attempt to go through the connection setup process again.

Link to this callback

init(atom, options) View Source
init(:consumer, options()) :: {:ok, options()} | :ignore

A callback executed when the consumer is started.

Returning {:ok, opts} - where opts is a keyword list of t:option() will, cause start_link/3 to return {:ok, pid} and the process to enter its loop.

Returning :ignore will cause start_link/3 to return :ignore and the process will exit normally without entering the loop