Prism v0.1.0 Prism View Source

Prism is a simple local message broker.

With this module, you can subscribe handlers to topics. When an event is published to the broker - any subscriber of that topic will have its handler function called. This permits simple event-driven mechanisms to be implemented within applications.

Prism avoids the use of processes when publishing events to subscribers. In that sense - handlers are all invoked in the publishing process. If you wish something to be done "out of band" from the publisher - you will be resposibsle for the implementation.

Example

defmodule MyBroker do
  use Prism

  def start_link(subscribers \\ []) do
    Prism.start_link(name: __MODULE__, subscribers: subscribers)
  end

  def subscribe(handler_id, topic_or_topics, handler) do
    Prism.subscribe(__MODULE__, handler_id, topic_or_topics, handler)
  end

  def publish(topic, event) do
    Prism.publish(__MODULE__, topic, event)
  end
end

defmodule Callback do
  def call(topic, event) do
    IO.inspect(topic)
    IO.inspect(event)
    :ok
  end
end

# Start the broker
MyBroker.start_link()

# Subscribe a handler
MyBroker.subscribe("my_handler", [:my, :topic], &Callback.call/2)

# Publish to a topic
MyBroker.publish([:my, :topic], "hello")

Link to this section Summary

Types

The unique broker identifier

The custom payload sent to event handlers

A function invoked when publishing events

The unique event handler identifier

Option values used by start_link/1

Options used by start_link/1

The result of a publish for a single event handler

The result of a publish

A tuple used to describe a subscriber

A list of subscribers

The name of a topic

A list of topics

Functions

Deletes a handler from the broker.

Publishes an event to subscribers of the given topic.

Starts a message broker process.

Subscribes a handler to a topic or topics within the broker.

Link to this section Types

Specs

broker_id() :: atom()

The unique broker identifier

Specs

event() :: term()

The custom payload sent to event handlers

Specs

handler() :: (topic(), event() -> any())

A function invoked when publishing events

Specs

handler_id() :: term()

The unique event handler identifier

Specs

option() :: {:name, broker_id()} | {:subscribers, subscribers()}

Option values used by start_link/1

Specs

options() :: [option()]

Options used by start_link/1

Specs

result() :: {handler_id(), term()}

The result of a publish for a single event handler

Specs

results() :: [result()]

The result of a publish

Specs

subscriber() :: {handler_id(), topics(), handler()}

A tuple used to describe a subscriber

Specs

subscribers() :: [subscriber()]

A list of subscribers

Specs

topic() :: [atom(), ...]

The name of a topic

Specs

topics() :: [topic()]

A list of topics

Link to this section Functions

Link to this function

delete(broker_id, handler_id, timeout \\ 5000)

View Source

Specs

delete(broker_id(), handler_id(), timeout()) :: :ok | {:error, term()}

Deletes a handler from the broker.

Handlers that are deleted will no longer recieve events that are published to the broker.

Examples

iex> Prism.subscribe(:my_broker, "my_handler", [:foo, :bar], &Callback.call/2)
:ok

iex> Prism.delete(:my_broker, "my_handler")
:ok
Link to this function

publish(broker_id, topic, event)

View Source

Specs

publish(broker_id(), topic(), event()) :: results()

Publishes an event to subscribers of the given topic.

Publishing is done in a syncronous manner within the calling process. If you need work to be done "out of bound" of the publisher - its your responsibility to implement it in that way. Any exceptions raised by a handler will also propagate to the publisher.

This will return a list of results in the format {handler_id, result}, where result is what is returned by the handler.

Examples

iex> Prism.subscribe(:my_broker, "my_handler", [:foo, :bar], fn topic, event -> {topic, event} end)
:ok

iex> Prism.publish(:my_broker, [:foo, :bar], "hello")
[{"my_handler", {[:foo, :bar], "hello"}}]

Specs

start_link(options()) :: GenServer.on_start()

Starts a message broker process.

Options

  • :name - The name of the broker process.
  • :subscribers - A list of subscribers to start the broker with.
Link to this function

subscribe(broker_id, handler_id, topic_or_topics, handler, timeout \\ 5000)

View Source

Specs

subscribe(broker_id(), handler_id(), topic() | topics(), handler(), timeout()) ::
  :ok | {:error, reason :: atom()}

Subscribes a handler to a topic or topics within the broker.

handler_id must be unique. If another handler with the same ID already exists then {:error, :already_exists} is returned. topic_or_topics is a list or list of lists containing atoms that describe an event occurance. handler is a 2-arity function that is called when an event is published to a subscribed topic.

Due to how anonymous functions are implemented in the Erlang VM, it is best to use function captures (i.e. &Mod.fun/2) as handlers to achieve maximum performance. In other words, avoid using literal anonymous functions (fn ... -> ... end) or local function captures (&handle_event/2) as handlers.

Please see publish/3 for information on publishing to subscribers.

Examples

iex> Prism.subscribe(:my_broker, "my_handler", [:foo, :bar], &Callback.call/2)
:ok

iex> Prism.subscribe(:my_broker, "my_handler", [:foo, :bar], &Callback.call/2)
{:error, :already_exists}

iex> Prism.subscribe(:my_broker, "my_other_handler", [[:foo, :bar], [:bar, :baz]], &Callback.call/2)
:ok