Elixir MOM v0.5.3 MOM.Channel protocol
A channel of communication. Subscribers are functions that will be called when somebody sends a message.
There are several error conditions:
- If a function raises an exception it is sent to the
:invalid
channel, - if there are no subscriber to the channel, it is sent to
:deadletter
channel - if the function raises an EXIT it will be removed from the functions to call
There are several types of channels: named, broadcast and point to point. Named channels are broadcast channels with a name as an atom, as :invalid.
Examples
iex> require Logger
iex> alias MOM.{Message, Channel}
iex> {:ok, ch} = Channel.Broadcast.start_link
iex> Channel.subscribe(ch, fn msg -> Logger.info("Message1 #{inspect msg}") end)
iex> Channel.subscribe(ch, fn msg -> Logger.info("Message2 #{inspect msg}") end)
iex> Channel.send(ch, %Message{ payload: %{method: "echo", param: "Hello world" }})
:ok
iex> Channel.unsubscribe(ch, 1)
:ok
It is allowed to call the channels after an atom
iex> require Logger
iex> alias MOM.{Message, Channel}
iex> Channel.Named.start_link
iex> id = Channel.subscribe(:deadletter, fn m -> Logger.error("Deadletter #{inspect m}") end)
iex> Channel.send(:empty, %Message{}) # always returns ok
iex> Channel.unsubscribe(:deadletter, id)
:ok
Channel subscription
In a broadcast channel the return value of the called function
is discarded, but on other implementations may require :ok
, :nok
or :empty
for further processing, so its good practive to return these values in your
functions.
Options:
front:
(true|false) — The subscriber is added at the front so it will be called first. Useful for tapping, for example. Default false.
Examples
A subscription normally calls a function when a message arrives
iex> alias MOM.{Channel, Message}
iex> require Logger
iex> {:ok, ch} = Channel.Broadcast.start_link
iex> Channel.subscribe(ch, fn _ ->
...> Logger.info("Called")
...> end)
iex> Channel.send(ch, %MOM.Message{ id: 0 })
:ok
Its possible to subscribe to named channels
iex> alias MOM.{Channel, Message}
iex> Channel.subscribe(:named_channel, fn _ -> :ok end)
iex> Channel.send(:named_channel, %Message{})
:ok
Its possible to subscribe a channel to a channel. This is useful to create tree like structures where some channels automatically write to another.
All messages in orig are send automatically to dest.
iex> require Logger
iex> alias MOM.{Channel, Message}
iex> {:ok, a} = Channel.Broadcast.start_link
iex> {:ok, b} = Channel.Broadcast.start_link
iex> Channel.subscribe(a, b)
iex> Channel.subscribe(b, fn _ ->
...> Logger.info("B called")
...> end)
iex> Channel.send(a, %MOM.Message{ id: 0, payload: "test"})
:ok