Antenna (antenna v0.1.0)
View SourceAntenna
is a mixture of Phoenix.PubSub
and
:gen_event
functionality with some batteries included.
It implements back-pressure on top of GenStage
, is fully conformant with
OTP Design Principles. and
is distributed out of the box.
One can have as many isolated Antenna
s as necessary, distinguished by t:id()
.
The workflow looks like shown below.
Sequence Diagram
sequenceDiagram
Consumer->>+Broadcaster: event(channel, event)
Broadcaster-->>+Consumer@Node1: event
Broadcaster-->>+Consumer@Node2: event
Broadcaster-->>+Consumer@NodeN: event
Consumer@Node1-->>-NoOp: mine?
Consumer@NodeN-->>-NoOp: mine?
Consumer@Node2->>Matchers: event
Matchers->>Handlers: handle_match/2
Usage Example
The consumer of this library is supposed to declare one or more matchers, subscribing to one
or more channels, and then call Antenna.event/2
to propagate the event.
assert {:ok, _pid, "{:tag_1, a, _} when is_nil(a)"} =
Antenna.match(Antenna, {:tag_1, a, _} when is_nil(a), self(), channels: [:chan_1])
assert :ok = Antenna.event(Antenna, [:chan_1], {:tag_1, nil, 42})
assert_receive {:antenna_event, :chan_1, {:tag_1, nil, 42}}
Summary
Types
The identifier of the channel, messages can be sent to, preferrably atom()
The event being sent to the listeners
The actual handler to be associated with an event(s). It might be either a function or a process id, in which case the message of a following shape will be sent to it.
Functions
Sends an event to all the associated matchers through channels.
Declares a matcher for tagged events.
Returns a map of matches to matchers
Subscribes a matcher process specified by pid
to a channel(s)
Undeclares a matcher for tagged events previously declared with Antenna.match/4
.
Unsubscribes a previously subscribed matcher process specified by pid
from the channel(s)
Types
The identifier of the channel, messages can be sent to, preferrably atom()
@type event() :: term()
The event being sent to the listeners
@type handler() :: (event() -> :ok) | (channel(), event() -> :ok) | Antenna.Matcher.t() | pid() | GenServer.name()
The actual handler to be associated with an event(s). It might be either a function or a process id, in which case the message of a following shape will be sent to it.
{:antenna_event, channel, event}
@type id() :: module()
The identifier of the isolated Antenna
Functions
Sends an event to all the associated matchers through channels.
The special :*
might be specified as channels, then the event
will be sent to all the registered channels.
Declares a matcher for tagged events.
Example
Antenna.match(Antenna, %{tag: _, success: false}, fn channel, message ->
Logger.warning("The processing failed for [" <>
inspect(channel) <> "], result: " <> inspect(message))
end, channels: [:rabbit])
@spec registered_matchers(id :: id()) :: %{ required(term()) => {pid(), Supervisor.child_spec()} }
Returns a map of matches to matchers
Subscribes a matcher process specified by pid
to a channel(s)
Undeclares a matcher for tagged events previously declared with Antenna.match/4
.
Accepts both an original match or a name returned by Antenna.match/4
,
which is effectively Macro.to_string(match)
.
Example
Antenna.unmatch(Antenna, %{tag: _, success: false})
Unsubscribes a previously subscribed matcher process specified by pid
from the channel(s)