Commanded.Aggregates.AggregateLifespan behaviour (Commanded v1.3.1) View Source
The Commanded.Aggregates.AggregateLifespan
behaviour is used to control the
aggregate GenServer
process lifespan.
By default an aggregate instance process will run indefinitely once started.
You can change this default by implementing the
Commanded.Aggregates.AggregateLifespan
behaviour in a module and configuring
it in your router.
After a command successfully executes, and creates at least one domain event,
the after_event/1
function is called passing the last created event.
When a command is successfully handled but results in no domain events (by
returning nil
or an empty list []
), the command struct is passed to the
after_command/1
function.
Finally, if there is an error executing the command, the error reason is
passed to the after_error/1
function.
For all the above, the returned inactivity timeout value is used to shutdown the aggregate process if no other messages are received.
Supported return values
- Non-negative integer - specify an inactivity timeout, in millisconds.
:infinity
- prevent the aggregate instance from shutting down.:hibernate
- send the process into hibernation.:stop
- immediately shutdown the aggregate process with a:normal
exit reason.{:stop, reason}
- immediately shutdown the aggregate process with the given reason.
Hibernation
A hibernated process will continue its loop once a message is in its message queue. Hibernating an aggregate causes garbage collection and minimises the memory used by the process. Hibernating should not be used aggressively as too much time could be spent garbage collecting.
Example
Define a module that implements the Commanded.Aggregates.AggregateLifespan
behaviour:
defmodule BankAccountLifespan do
@behaviour Commanded.Aggregates.AggregateLifespan
def after_event(%MoneyDeposited{}), do: :timer.hours(1)
def after_event(%BankAccountClosed{}), do: :stop
def after_event(_event), do: :infinity
def after_command(%CloseAccount{}), do: :stop
def after_command(_command), do: :infinity
def after_error(:invalid_initial_balance), do: :timer.minutes(5)
def after_error(_error), do: :stop
end
Then specify the module as the lifespan
option when registering the
applicable commands in your router:
defmodule BankRouter do
use Commanded.Commands.Router
dispatch [OpenAccount, CloseAccount],
to: BankAccount,
lifespan: BankAccountLifespan,
identity: :account_number
end
Link to this section Summary
Callbacks
Aggregate process will be stopped after specified inactivity timeout unless
:infinity
, :hibernate
, or :stop
are returned.
Aggregate process will be stopped after specified inactivity timeout unless
:infinity
, :hibernate
, or :stop
are returned.
Aggregate process will be stopped after specified inactivity timeout unless
:infinity
, :hibernate
, or :stop
are returned.
Link to this section Types
Specs
Link to this section Callbacks
Specs
Aggregate process will be stopped after specified inactivity timeout unless
:infinity
, :hibernate
, or :stop
are returned.
Specs
Aggregate process will be stopped after specified inactivity timeout unless
:infinity
, :hibernate
, or :stop
are returned.
Specs
Aggregate process will be stopped after specified inactivity timeout unless
:infinity
, :hibernate
, or :stop
are returned.