Packages
x3m_system
0.4.5
0.9.1
0.9.0
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
retired
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
retired
0.7.7
0.7.6
retired
0.7.5
0.7.4
retired
0.7.3
retired
0.7.2
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
retired
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.1.1
0.1.0
Building blocks for distributed and/or CQRS/ES systems
Current section
Files
Jump to
Current section
Files
lib/aggregate.ex
defmodule X3m.System.Aggregate do
defmodule State do
@type t :: %__MODULE__{version: integer, client_state: any}
defstruct version: -1, client_state: nil
end
@callback initial_state :: map()
@spec initial_state(atom) :: State.t()
def initial_state(aggregate_mod),
do: %State{client_state: apply(aggregate_mod, :initial_state, [])}
defmacro handle_msg(msg_name, fun) do
quote do
@spec unquote(msg_name)(X3m.System.Message.t(), X3m.System.Aggregate.State.t()) ::
{:block | :noblock, X3m.System.Message.t(), X3m.System.Aggregate.State.t()}
def unquote(msg_name)(%X3m.System.Message{} = message, state) do
X3m.System.Instrumenter.execute(:handle_msg, %{}, %{
aggregate: __MODULE__,
message: unquote(msg_name)
})
client_state = state.client_state || raise("Aggregate state wasn't set")
{label, %X3m.System.Message{} = message, client_state} =
unquote(fun).(message, client_state)
{label, message, %State{state | client_state: client_state}}
end
end
end
defmacro __using__(_opts) do
quote do
alias X3m.System.Aggregate
alias X3m.System.Aggregate.State, as: AggregateState
require Aggregate
import Aggregate
@behaviour Aggregate
@doc false
def apply_events([event | tail], last_version, %AggregateState{} = state) do
new_client_state = apply_event(event, state.client_state)
apply_events(tail, last_version, %AggregateState{state | client_state: new_client_state})
end
def apply_events([], last_version, %AggregateState{} = state),
do: %AggregateState{state | version: last_version}
@before_compile X3m.System.Aggregate
end
end
defmacro __before_compile__(_env) do
quote do
defp apply_event(_event, state),
do: state
end
end
end