defmodule Finitomata.Pool.Actor do @moduledoc """ The behaviour specifying the actor in the pool. """ alias Finitomata.{Pool, Pool.Actor, State} @doc """ The function which would be invoked in `Finitomata.Pool.run/3`, see `t:Finitomata.Pool.responsive_actor/0` """ @callback actor(term(), State.payload()) :: {:ok, term()} | {:error, any()} @doc """ The function which would be invoked in `Finitomata.Pool.run/3` after `actor/2` returned successfully with a result of invocation and the state of the `Pool` worker, see `t:Finitomata.Pool.naive_handler/0`. The value returned from this call will be send as an last argument of the message to the caller of `Finitomata.Pool.run/3` if the `pid` was passed. """ @callback on_result(result :: term(), id :: Pool.id()) :: any() @doc """ The function which would be invoked in `Finitomata.Pool.run/3` after `actor/2` failed with a failure message and the state of the `Pool` worker, see `t:Finitomata.Pool.naive_handler/0`. The value returned from this call will be send as an last argument of the message to the caller of `Finitomata.Pool.run/3` if the `pid` was passed. """ @callback on_error(error :: term(), id :: Pool.id()) :: any() @optional_callbacks on_result: 2, on_error: 2 @doc """ `StreamData` helper to produce `on_error/2` and `on_result/2` handlers """ def handler, do: handler(:result) def handler(:error), do: do_handler(error: true) def handler(:result), do: do_handler(error: false) def handler(f) when is_function(f, 2), do: do_handler(handler: f) defp do_handler(options) when is_list(options) do default = fn -> if Keyword.get(options, :error, false), do: &Actor.error_logger/2, else: &Actor.result_logger/2 end handler = Keyword.get_lazy(options, :handler, default) StreamData.constant(handler) end @doc false def result_logger(result, id) do require Logger Logger.info("[👷] Pool worker: ‹#{inspect(id)}› succeeded: ‹#{inspect(result)}›") end @doc false def error_logger(error, id) do require Logger Logger.warning("[👷] Pool worker: ‹#{inspect(id)}› errored: ‹#{inspect(error)}›") end end