View Source Actors.Actor.Entity.Invocation (spawn v2.0.0-RC10)

Handles Invocation functions for Actor Entity All the public functions here assumes they are executing inside a GenServer

Summary

Functions

do_broadcast(request, broadcast, opts \\ [])

do_side_effects(request, effects, opts \\ [])

handle_response(request, response, state, opts)

handle_timers(timers, system, actor)

invoke(arg, state)

Handles the invocation of actions on an Actor Entity.

Parameters

  • invocation (%InvocationRequest{}): A struct representing the invocation request, including details about the actor, action, and payload.
  • opts (Keyword.t): Additional options for the invocation.

Returns

  • {:reply, result, new_state}: If the invocation is successful, returns a tuple containing the reply result, and the updated entity state.
  • {:noreply, new_state}: If the invocation is successful, but there is no specific reply result.
  • {:noreply, new_state, opts}: If the invocation is successful and includes additional options.
  • {:error, reason, new_state}: If there is an error during the invocation, returns a tuple with the reason for the error and the updated entity state.

Behavior

The invoke/2 function is responsible for handling the invocation of actions on an Actor Entity. It verifies authorization, finds the appropriate action to execute, and delegates the invocation to the corresponding interface.

The function performs the following steps:

  1. Authorization Check: Checks if the invocation is authorized based on the actor's actions and timers.

  2. Span Context Handling: Uses OpenTelemetry for tracing and creates a new span for the invocation.

  3. Find Request by Action: Determines the appropriate interface and builds the request based on the action.

  4. Invocation Host Handling: Delegates the invocation to the selected interface's invoke_host/3 function.

  5. Handle Response: Processes the response from the invocation, handles side effects, and updates the entity state.

  6. Checkpoint: Optionally performs a checkpoint operation to record the state revision.

Example

invocation = %InvocationRequest{
  actor: %Actor{id: %ActorId{name: "example_actor"}},
  action_name: "perform_action",
  payload: {:data, %{}},
  caller: %ActorId{name: "caller_actor"}
}

opts = [span_ctx: OpenTelemetry.Ctx.new()]

case Actors.Actor.Entity.Invocation.invoke({invocation, opts}, entity_state) do
  {:reply, result, new_state} ->
    IO.puts("Invocation successful! Result: {result}")
  {:noreply, new_state} ->
    IO.puts("Invocation successful! No specific reply.")
  {:error, reason, new_state} ->
    IO.puts("Invocation failed. Reason: {reason}")
end

invoke_init(state)

Handles the initialization invocation for an Actor Entity.

Parameters

  • state (%EntityState{}): The current state of the Actor Entity.

Returns

  • {:noreply, new_state}: If the initialization is successful.
  • {:noreply, new_state}: If the actor has not registered any actions, indicating a warning.
  • {:error, reason, new_state}: If there is an error during the initialization, returns a tuple with the reason for the error and the updated entity state.

Behavior

The invoke_init/1 function is responsible for handling the initialization invocation of an Actor Entity. It checks if the actor has registered any actions and performs the following steps:

  1. Action Registration Check: Checks if the actor has registered any actions. If not, it logs a warning and returns {:noreply, new_state}.

  2. Init Action Selection: Filters the registered actions to find the initialization action (init or similar) and selects the first matching action.

  3. Interface Invocation: Invokes the selected initialization action using the appropriate interface.

  4. Handling Initialization Result: Processes the result of the initialization, updating the entity state accordingly.

Example

state = %EntityState{
  system: %ActorSystem{name: "example_system"},
  actor: %Actor{
    id: %ActorId{name: "example_actor"},
    actions: ["init", "perform_action"],
    state: %{}
  },
  opts: %{}
}

case Actors.Actor.Entity.Invocation.invoke_init(state) do
  {:noreply, new_state} ->
    IO.puts("Initialization successful!")
  {:error, reason, new_state} ->
    IO.puts("Initialization failed. Reason: {reason}")
end

process_projection_events(messages, state)

replay(call_opts, state)

replay(replaymsg, call_opts, state)