Current section

Files

Jump to
extreme_system lib system rabbitmq channel_manager.ex
Raw

lib/system/rabbitmq/channel_manager.ex

defmodule Extreme.System.RabbitMQ.ChannelManager do
use GenServer
alias AMQP.Channel
require Logger
### Client API
@doc """
Starts the RabbitMQ connection.
"""
def start_link(connection_name, opts),
do: GenServer.start_link __MODULE__, connection_name, opts
def get_channel(server, listener),
do: GenServer.call server, {:get_channel, listener}
def get_channel(server, publisher, target),
do: GenServer.call server, {:get_channel, publisher, target}
### Server Callbacks
def init(connection_name) do
conn = Extreme.System.RabbitMQ.Connection.get_connection connection_name
Process.link conn.pid
{:ok, %{connection: conn, channel_mappings: %{listeners: %{}, publishers: %{}}}}
end
def handle_call({:get_channel, listener}, _from, %{connection: conn, channel_mappings: %{listeners: mappings}}=state) do
new_mappings = _add_channel_mapping conn, listener, mappings
chan = new_mappings |> Map.get(listener)
{:reply, chan, put_in(state[:channel_mappings][:listeners], new_mappings)}
end
def handle_call({:get_channel, publisher, target}, _from, %{connection: conn, channel_mappings: %{publishers: mappings}}=state) do
new_mappings = _add_channel_mapping conn, publisher, target, mappings
chan = new_mappings |> get_in([publisher, target])
{:reply, chan, put_in(state[:channel_mappings][:publishers], new_mappings)}
end
def handle_call(:get_state, _from, state),
do: {:reply, state, state}
defp _add_channel_mapping(conn, listener, mappings) do
Map.put_new_lazy(mappings, listener, fn() -> _create_channel(conn) end)
end
defp _add_channel_mapping(conn, publisher, target, mappings) do
case get_in(mappings, [publisher, target]) do
nil ->
publisher_map = mappings
|> Map.get(publisher, %{})
|> Map.put(target, _create_channel(conn))
mappings |> Map.put(publisher, publisher_map)
_ -> mappings
end
end
defp _create_channel(conn) do
{:ok, chan} = Channel.open conn
chan
end
end