Ankusa.Sink.RabbitMQ.Connection (ankusa_rabbitmq v0.7.0)

Copy Markdown View Source

One AMQP connection + confirm-mode channel per {instance, url, exchange}. Declares the configured exchange whenever it opens the channel (idempotent) — never a queue; queue ownership belongs to consumers, not this sink.

Every publish is mandatory and is answered on the broker's confirm of that publish, so publish/4 answers :ok only when at least one queue bound to the exchange accepted the message. A message the exchange routes to no queue is {:error, {:unroutable, routing_key}}, one the broker refuses (a queue's reject-publish overflow) is {:error, :nacked}, and no confirm within :confirm_timeout_ms milliseconds is {:error, :confirm_timeout}.

Confirms are asynchronous

A publish is sent and its caller parked under the publish's sequence number; the confirm, whenever it arrives, answers it. Many publishes are in flight on the channel at once (up to :max_inflight, default 256; past that a publish is {:error, :busy}), so one slow confirm never serializes the others.

Every call carries its caller's deadline. A publish still waiting in this process's mailbox when its caller gave up (publish/4 waits 15 s) is answered {:error, :expired} and never sent: an abandoned call is not published behind the caller's back.

The channel is monitored. When the broker closes it (a publish to a deleted exchange is a 404) every publish waiting on it answers {:error, {:channel_closed, reason}} and the channel is reopened at once on the same connection, re-declaring the exchange.

The connection dials after start_link/1 returns, and connection loss is not treated as a crash — this GenServer stays up and retries on a timer, replying {:error, :not_connected} to publishes in the meantime (and to any that were waiting when it dropped). Every one of these errors flows into the source's Ankusa.RetryPolicy exactly like any other sink failure, so there is no separate reconnect policy to get wrong.

The AMQP connection belongs to amqp_client's own supervisor, not to this process, so stopping this process (its supervisor's shutdown, or the idle sweep of Ankusa.Sink.Reaper) closes it explicitly and answers every waiting publish {:error, :not_connected}.

Summary

Functions

The longest publish/4 waits, in milliseconds.

Returns a specification to start this module under a supervisor.

The AMQP URL this connection uses when :url is not configured.

Functions

call_timeout_ms()

@spec call_timeout_ms() :: pos_integer()

The longest publish/4 waits, in milliseconds.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

default_url()

@spec default_url() :: String.t()

The AMQP URL this connection uses when :url is not configured.

publish(server, routing_key, payload, props \\ [])

@spec publish(GenServer.server(), String.t(), binary(), keyword()) ::
  :ok | {:error, term()}

start_link(opts)