Current section

Files

Jump to
evoq src evoq_aggregate_lifespan_default.erl
Raw

src/evoq_aggregate_lifespan_default.erl

%% @doc Default aggregate lifespan implementation.
%%
%% Provides sensible defaults for aggregate lifecycle:
%% - 30-minute idle timeout
%% - 5-minute timeout on errors
%% - Automatic snapshot on passivation
%%
%% This prevents the memory explosion that occurs when aggregates
%% live indefinitely (as in Commanded's default lifespan).
%%
%% @author rgfaber
-module(evoq_aggregate_lifespan_default).
-behaviour(evoq_aggregate_lifespan).
-include("evoq.hrl").
%% Behavior callbacks
-export([after_event/1, after_command/1, after_error/1]).
-export([on_timeout/1, on_passivate/1]).
%%====================================================================
%% Behavior callbacks
%%====================================================================
%% @doc Return timeout after processing an event.
%% Resets the idle timer to the default 30 minutes.
-spec after_event(map()) -> evoq_aggregate_lifespan:action().
after_event(_Event) ->
get_idle_timeout().
%% @doc Return timeout after processing a command.
%% Resets the idle timer to the default 30 minutes.
-spec after_command(map()) -> evoq_aggregate_lifespan:action().
after_command(_Command) ->
get_idle_timeout().
%% @doc Return timeout after an error.
%% Uses a shorter timeout (5 minutes) to allow faster recovery.
-spec after_error(term()) -> evoq_aggregate_lifespan:action().
after_error(_Error) ->
300000. %% 5 minutes
%% @doc Handle timeout by passivating with snapshot.
-spec on_timeout(term()) -> {snapshot, passivate}.
on_timeout(_State) ->
{snapshot, passivate}.
%% @doc Return snapshot data on passivation.
-spec on_passivate(term()) -> {ok, term()}.
on_passivate(State) ->
{ok, State}.
%%====================================================================
%% Internal functions
%%====================================================================
%% @private
get_idle_timeout() ->
application:get_env(evoq, idle_timeout, ?DEFAULT_IDLE_TIMEOUT).