Packages
rambla
1.4.0
1.5.0
1.4.2
1.4.1
1.4.0
1.3.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.1
1.0.0
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.0
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
0.13.0
0.12.2
0.12.1
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Easy publishing to many different targets. Supported back-ends: - Rabbit [Amqp](https://hexdocs.pm/amqp/) - Redis [Redix](https://hexdocs.pm/redix) - Http [:httpc](http://erlang.org/doc/man/httpc.html) - Smtp [:gen_smtp](https://hexdocs.pm/gen_smtp) - Slack [Envío](https://hexdocs.pm/envio)
Current section
Files
Jump to
Current section
Files
lib/rambla/connections/amqp.ex
defmodule Rambla.Amqp do
@moduledoc """
Default connection implementation for 🐰 Rabbit.
`publish/2` accepts the following options:
- `exchange` [`binary()`, **mandatory**] the exchange to publish to
- `queue` [`binary()`, **optional**] if passed, the queue will be created
and bound to the exchange; it’s slowing down publishing, but safer
for the cold RebbatMQ installation
- `declare?`[`boolean()`, **optional**, _default_: `true`] if false
is passed, the exchange would not be declared; use it if the exchange
already surely exists to speed up the publishing
- `routing_key` [`binary()`, **optional**, _default_: `""`] if passed,
used as a routing key
- `options` [`keyword()`, **optional**, _default_: `[]`] the options
to be passed as is to call to `AMQP.Basic.publish/5`
---
Since `v0.6.0` provides two `mix` tasks:
- `mix rambla.rabbit.exchange` Operations with exchanges in RabbitMQ
- `mix rambla.rabbit.queue` Operations with queues in RabbitMQ
Tasks support arguments to be passed to RabbitMQ instance. Usage example:
```
mix rambla.rabbit.queue declare foo -o durable:true
```
"""
defmodule ChannelPool do
@moduledoc false
@spec publish(Rambla.Connection.Config.t(), binary() | map() | list()) :: {:ok, any()}
def publish(%Rambla.Connection.Config{conn: conn} = cfg, message) do
do_publish(conn, cfg, message)
end
defp do_publish(
conn,
%Rambla.Connection.Config{conn: conn, chan: chan, opts: opts},
message
) do
message =
case message do
message when is_binary(message) -> message
%{} = message -> Jason.encode!(message)
[{_, _} | _] = message -> message |> Map.new() |> Jason.encode!()
message -> inspect(message)
end
with %{exchange: exchange} <- opts,
declare? <- Map.get(opts, :declare?, true),
if(declare?, do: apply(AMQP.Exchange, :declare, [chan, exchange])),
:ok <- queue!(chan, opts) do
apply(AMQP.Basic, :publish, [
chan,
exchange,
Map.get(opts, :routing_key, ""),
message,
Map.get(opts, :options, [])
])
{:ok, message}
else
error -> {:error, error}
end
end
@spec queue!(chan :: AMQP.Channel.t(), map()) :: :ok
defp queue!(chan, %{queue: queue, exchange: exchange}) do
with {:ok, %{consumer_count: _, message_count: _, queue: ^queue}} <-
apply(AMQP.Queue, :declare, [chan, queue]),
do: apply(AMQP.Queue, :bind, [chan, queue, exchange])
end
defp queue!(_, %{exchange: _exchange}), do: :ok
end
@behaviour Rambla.Connection
@impl Rambla.Connection
def publish(%Rambla.Connection.Config{} = conn, message)
when is_binary(message) or is_list(message) or is_map(message),
do: ChannelPool.publish(conn, message)
@impl Rambla.Connection
if match?({:module, _}, Code.ensure_compiled(AMQP.Channel)) do
def connect(params) when is_list(params) do
with {:ok, _host} <- Keyword.fetch(params, :host),
{:ok, conn} <- AMQP.Connection.open(params),
{:ok, chan} <- AMQP.Channel.open(conn) do
Process.link(conn.pid)
%Rambla.Connection{
conn: %Rambla.Connection.Config{conn: conn, chan: chan},
conn_type: __MODULE__,
conn_pid: conn.pid,
conn_params: params,
errors: []
}
else
:error ->
raise(Rambla.Exceptions.Connection,
value: params,
source: __MODULE__,
reason: "inconsistent params",
expected: "🐰 configuration with :host key"
)
error ->
%Rambla.Connection{
conn: %Rambla.Connection.Config{},
conn_type: __MODULE__,
conn_pid: nil,
conn_params: params,
errors: [error]
}
end
end
else
def connect(params) do
raise(Rambla.Exceptions.Connection,
source: __MODULE__,
info: params,
source: __MODULE__,
reason: "missing dependencies",
expected: "🐰 Rabbit must be added to `deps()`"
)
end
end
end