Packages

A toolkit for building event-driven applications in Elixir with event sourcing and CQRS patterns

Current section

Files

Jump to
ex_sorcery lib sorcery pub_sub.ex
Raw

lib/sorcery/pub_sub.ex

defmodule Sorcery.PubSub do
@moduledoc """
Provides a clean interface for publishing and subscribing to events.
## Configuration
In your config.exs:
config :sorcery, :pub_sub,
pub_sub: Sorcery.PubSub.PostgresStore,
pub_sub_opts: [
repo: MyApp.Repo,
table_name: "events"
]
Or for in-memory storage:
config :sorcery, :pub_sub,
pub_sub: Sorcery.PubSub.MemoryStore
## Usage
# Publish an event
event = Sorcery.Event.new(%{
type: "user_registered",
data: %{user_id: "123"},
domain: "users",
instance_id: "instance_1",
domain_sequence_number: 1
})
Sorcery.PubSub.publish(event)
# Subscribe to events
{:ok, events, pagination} = Sorcery.PubSub.subscribe()
# Query specific events
{:ok, events, pagination} = Sorcery.PubSub.subscribe_by_domain("users")
{:ok, events, pagination} = Sorcery.PubSub.subscribe_by_type("user_registered")
"""
alias Sorcery.Event
alias Sorcery.PubSub.Behaviour
@type subscription :: Behaviour.subscription()
def child_spec(opts) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [opts]},
type: :worker,
restart: :permanent,
shutdown: 5000
}
end
@doc """
Publishes one or more events to the configured store.
"""
@spec publish(Event.t() | [Event.t()]) :: :ok | {:error, term()}
def publish(events) do
pub_sub().publish(events)
end
@doc """
Subscribes to events for a given subscription.
"""
@spec subscribe() :: :ok | {:error,term()}
def subscribe() do
pub_sub().subscribe()
end
@spec pub_sub() :: module()
def pub_sub do
Application.get_env(:sorcery, :pub_sub, [])
|> Keyword.get(:pub_sub, Sorcery.PubSub.Registry)
end
@doc """
Returns the configured options for the pub sub.
"""
@spec pub_sub_opts() :: Keyword.t()
def pub_sub_opts do
Application.get_env(:sorcery, :pub_sub, [])
|> Keyword.get(:pub_sub_opts, [])
end
@doc """
Starts the configured pub sub.
"""
@spec start_link(Keyword.t()) :: GenServer.on_start()
def start_link(opts \\ []) do
pub_sub().start(pub_sub_opts() ++ opts)
end
end