Commanded v0.15.0 Commanded.Event.Handler behaviour View Source
Defines the behaviour an event handler must implement and provides a convenience macro that implements the behaviour, allowing you to handle only the events you are interested in processing.
You should start your event handlers using a Supervisor to ensure they are restarted on error.
Example
defmodule AccountBalanceHandler do
use Commanded.Event.Handler, name: __MODULE__
def init do
with {:ok, _pid} <- Agent.start_link(fn -> 0 end, name: __MODULE__) do
:ok
end
end
def handle(%BankAccountOpened{initial_balance: initial_balance}, _metadata) do
Agent.update(__MODULE__, fn _ -> initial_balance end)
end
def current_balance do
Agent.get(__MODULE__, fn balance -> balance end)
end
end
Start your event handler process (or use a Supervisor):
{:ok, _handler} = AccountBalanceHandler.start_link()
Event handler name
The name you specify is used when subscribing to the event store. Therefore you should not change the name once the handler has been deployed. A new subscription will be created when you change the name, and you event handler will receive already handled events.
Subscription options
You can choose to start the event handler’s event store subscription from
:origin
, :current
position, or an exact event number using the start_from
option. The default is to use the origin so your handler will receive all
events.
Use the :current
position when you don’t want newly created event handlers
to go through all previous events. An example would be adding an event handler
to send transactional emails to an already deployed system containing many
historical events.
Example
Set the start_from
option (:origin
, :current
, or an explicit event
number) when using Commanded.Event.Handler
:
defmodule AccountBalanceHandler do
use Commanded.Event.Handler,
name: "AccountBalanceHandler",
start_from: :origin
end
You can optionally override :start_from
by passing it as option when
starting your handler:
{:ok, _handler} = AccountBalanceHandler.start_link(start_from: :current)
Consistency
For each event handler you can define its consistency, as one of either
:strong
or :eventual
.
This setting is used when dispatching commands and specifying the consistency
option.
When you dispatch a command using :strong
consistency, after successful
command dispatch the process will block until all event handlers configured to
use :strong
consistency have processed the domain events created by the
command. This is useful when you have a read model updated by an event handler
that you wish to query for data affected by the command dispatch. With
:strong
consistency you are guaranteed that the read model will be
up-to-date after the command has successfully dispatched. It can be safely
queried for data updated by any of the events created by the command.
The default setting is :eventual
consistency. Command dispatch will return
immediately upon confirmation of event persistence, not waiting for any event
handlers.
Example
defmodule AccountBalanceHandler do
use Commanded.Event.Handler,
name: "AccountBalanceHandler",
consistency: :strong
end
Link to this section Summary
Functions
Macro as a convenience for defining an event handler
Callbacks
Event handler behaviour to handle a domain event and its metadata
Optional initialisation callback function called when the handler starts
Link to this section Types
subscribe_from() :: :origin | :current | non_neg_integer()
Link to this section Functions
Macro as a convenience for defining an event handler.
Example
defmodule ExampleHandler do
use Commanded.Event.Handler, name: "ExampleHandler"
def init do
# optional initialisation
:ok
end
def handle(%AnEvent{..}, _metadata) do
# ... process the event
:ok
end
Start event handler process (or configure as a worker inside a supervisor):
{:ok, handler} = ExampleHandler.start_link()
Link to this section Callbacks
handle(domain_event(), metadata()) :: :ok | {:error, :already_seen_event} | {:error, reason :: any()}
Event handler behaviour to handle a domain event and its metadata
Return :ok
on success, {:error, :already_seen_event}
to ack and skip the event, or {:error, reason}
on failure.
Optional initialisation callback function called when the handler starts.
Can be used to start any related processes when the event handler is started.
Return :ok
on success, or {:stop, reason}
to stop the handler process.