AMQPX v1.0.0 AMQPX.Receiver.Standard behaviour View Source

A message handler implementing some sane defaults.

This server should not be started directly; use the AMQPX.Receiver supervisor instead.

Each receiver sets up its own channel and makes sure it is disposed of when the receiver dies.

If you’re implementing your own receiver, remember to clean up channels to avoid leaking resources and potentially leaving messages stuck in unacked state.

Each receiver sets up a single queue and binds it with multiple routing keys, assigning to each key a handler module implementing the AMQPX.Receiver.Standard behaviour; read the callback documentation for details.

If the arriving message sets the reply_to and correlation_id attributes, the result of the message handler (or its crash reason) will be sent as a reply message. This is designed to work transparently in conjunction with AMQPX.RPC.

Message handler lifetime

Each message spawns a Task placed under a Task.Supervisor with graceful shutdown to help ensure that under normal shutdown all message handlers are allowed to finish their work and send the acks to the broker.

AMQPX provides a default supervisor process; however, to help ensure that message handlers have access to the resources they need, such as database connections, it is recommended that you start your own Task.Supervisor, set ample shutdown time, and place it in your supervision tree after the required resource but before the AMQPX.Receiver that will be spawning the handlers.

Codecs

AMQPX tries to separate message encoding and the business logic of message handlers with codecs.

A codec is a module implementing the AMQPX.Codec behaviour. The only codec provided out of the box is AMQPX.Codec.Text.

:text is shorthand for “text/plain” and is handled by AMQPX.Codec.Text by default.

:json is recognised as shorthand for application/json, but no codec is included in AMQPX; however, both Poison and Jason can be used as codec modules directly if you bundle them in your application.

Link to this section Summary

Callbacks

Takes the result or handle/2 or its crash reason and formats it in a way that a codec can handle

Called on every incoming message

Returns a term uniquely identifying this message

Tells the receiver whether to requeue messages when handle/2 crashes

Called when a message has been retried too many times and has been rejected

Link to this section Types

Link to this type exchange_declare_option() View Source
exchange_declare_option() ::
  {:name, String.t()} | {:type, atom()} | {:options, [exchange_option()]}
Link to this type exchange_option() View Source
exchange_option() ::
  {:declare, boolean()}
  | {:durable, boolean()}
  | {:passive, boolean()}
  | {:auto_delete, boolean()}
  | {:internal, boolean()}
  | {:no_wait, boolean()}
  | {:arguments, list()}
Link to this type option() View Source
option() ::
  {:connection, connection_id :: atom()}
  | {:name, atom()}
  | {:prefetch, integer()}
  | {:exchange,
     {type :: atom(), name :: String.t(), opts :: [exchange_option()]}
     | {type :: atom(), name :: String.t()}
     | (name :: String.t())}
  | {:declare_exchanges, [exchange_declare_option()]}
  | {:queue,
     nil
     | (name :: String.t())
     | (opts :: Keyword.t())
     | {name :: String.t(), opts :: Keyword.t()}}
  | {:keys,
     [String.t()]
     | %{
         required(routing_key :: String.t() | {String.t(), String.t()}) =>
           handler :: module()
       }}
  | {:handler, atom()}
  | {:codecs,
     %{required(mime_type :: String.t()) => :handler | (codec :: module())}}
  | {:supervisor, atom()}
  | {:name, atom()}
  | {:log_traffic, boolean()}
  | {:measurer, module()}
  | {:retry, [AMQPX.Receiver.Standard.Retry.option()]}
  | {:deduplicate, [AMQPX.Receiver.Standard.Deduplicate.option()]}

Link to this section Functions

Link to this function handle_handover(name, request) View Source
Link to this function start_link(args) View Source
start_link([option()]) :: {:ok, pid()}

Starts the process.

Options

  • :prefetch – set the prefetch count; defaults to 1
  • :exchange – the exchange to bind to. The exchange is expected to exist; set :declare to true to create it. Defaults to a durable topic exchange.
  • :declare_exchanges – a list of exchanges to declare during initialization
  • :queue – the queue to consume from. Defaults to an anonymous auto-deleting queue.
  • :keys – a set of routing keys to bind with and their corresponding handler modules, or just a list of keys. The handler modules must implement the AMQPX.Receiver.Standard behaviour. If a list is given, the :handler option must be set. Topic exchange wildcards ‘*’ and ‘#’ are supported.
  • :handler – the handler to use when no key-specific handler is set
  • :codecs – override the default set of codecs; see the Codecs section for details
  • :supervisor – the named Task.Supervisor to use for individual message handlers
  • :name – the name to register the process with

Link to this section Callbacks

Link to this callback format_response(response, meta) View Source
format_response(response :: any(), meta :: Map.t()) ::
  {mime_type :: :json | :text | String.t(), payload :: any()}
  | (payload :: any())

Takes the result or handle/2 or its crash reason and formats it in a way that a codec can handle.

Only used if the incoming message indicates that a reply is necessary.

payload will be passed through the codec indicated by mime_type. A payload with no matching codec for the declared MIME type will be sent as is. A bare payload string will be sent as is with the content type application/octet-stream.

Link to this callback handle(payload, meta) View Source
handle(payload :: any(), meta :: Map.t()) :: any()

Called on every incoming message.

The payload type will depend on the content type of the incoming message and the codec registered for that content type. If there is no matching codec for that content type, the payload will be passed as is.

Link to this callback handling_node(payload, meta) View Source (optional)
handling_node(payload :: any(), meta :: Map.t()) :: atom()
Link to this callback identity(payload, meta) View Source (optional)
identity(payload :: any(), meta :: Map.t()) :: term()

Returns a term uniquely identifying this message.

Used for tracking retry limits. The function must be deterministic for the tracker to work as intended.

Link to this callback requeue?() View Source (optional)
requeue?() :: true | false | :once

Tells the receiver whether to requeue messages when handle/2 crashes.

Be careful with choosing to always requeue. If the crash is not caused by some transient condition such as a lost database connection, but a permanent one such as a bug in the message handler or a payload that cannot be parsed, this will cause the message to be redelivered indefinitely at the highest rate supported by your hardware, putting high load on the broker, the network, and the host running your application. Consider using :retry to break the loop.

Defaults to false if not implemented.

Link to this callback retry_exhausted(payload, meta) View Source (optional)
retry_exhausted(payload :: any(), meta :: Map.t()) :: any()

Called when a message has been retried too many times and has been rejected.