Current section
Files
Jump to
Current section
Files
lib/orcha.ex
defmodule Orcha do
@type message() :: term()
@type timestamp() :: pos_integer()
@opaque t() :: %__MODULE__{
registry: %{atom() => any()}
}
@callback handle_request({module(), message()}, timestamp(), t()) ::
{{:ok, result :: term()}, t()} | {:error, reason :: term()}
defstruct registry: %{}
def initialize(_args \\ []), do: %__MODULE__{}
def register(%__MODULE__{} = realm, {mod, func, args}) do
state = apply(mod, func, args)
put_state(mod, state, realm)
end
def request({mod, msg}, timestamp, realm) do
with {:ok, state} <- Map.fetch(realm.registry, mod) do
case apply(mod, :handle_request, [msg, {timestamp, realm}, state]) do
{result, new_state} ->
new_realm = put_state(mod, new_state, realm)
{result, new_realm}
{result, new_state, %__MODULE__{} = new_realm} ->
new_realm = put_state(mod, new_state, new_realm)
{result, new_realm}
end
else
:error ->
raise "Requesting unregistered service: #{inspect(mod)}"
end
end
defp put_state(mod, state, %__MODULE__{} = realm) do
update_in(realm.registry, &Map.put(&1, mod, state))
end
end