View Source Actors.Actor.CallerConsumer (spawn v2.0.0-RC1)

An Elixir module representing a GenStage consumer responsible for handling events initiated by CallerProducer and interacting with actors in the system.

Summary

Functions

Performs the action of looking up or creating an actor based on the given parameters.

Gets the state of the specified actor.

Handles incoming events from the CallerProducer GenStage.

Initializes the GenStage consumer.

Invokes an actor action with distributed tracing using OpenTelemetry.

Performs a liveness check for a given actor identified by %ActorId{}.

Performs a readiness check for a given actor identified by %ActorId{}.

Registers actors in the system based on the provided registration request.

Spawns an actor or a group of actors based on the provided SpawnRequest.

Starts the consumer process and subscribes to the CallerProducer GenStage.

Tries to reactivate an actor.

Functions

do_lookup_action(system_name, actor_fqdn, system, action_fun)

Performs the action of looking up or creating an actor based on the given parameters.

This function is responsible for looking up or creating an actor based on the specified actor fully-qualified domain name (FQDN). It incorporates distributed tracing with OpenTelemetry to capture relevant events and attributes during the lookup or creation process.

Parameters

  • system_name (String): The name of the actor system.
  • actor_fqdn (tuple): A tuple representing the fully-qualified domain name (FQDN) of the actor.
  • system (%ActorSystem{}): The actor system.
  • action_fun (function): The function to be invoked once the actor is looked up or created. It receives the actor reference and actor reference ID as parameters.

Tracing Context

The function sets up a span with the name "actor-lookup" to trace the lookup or creation process. It adds relevant attributes, such as the actor FQDN, to the tracing context.

Retry Mechanism

The function incorporates a retry mechanism with backoff, randomization, and timeout to handle potential errors during the lookup or creation process.

Returns

The result of the action_fun function or an error tuple in case of failure.

Error Handling

In case of errors during the lookup or creation process, appropriate logging and tracing events are added, and the error is returned as part of the result tuple.

get_state(id)

Gets the state of the specified actor.

This function attempts to retrieve the state of the actor identified by the given ActorId. It uses an exponential backoff strategy for retrying in case of errors and logs any failures.

Parameters

  • id (%ActorId): The unique identifier of the actor.

Returns

The state of the actor if successful, otherwise an error is raised.

Retry Strategy

The function utilizes an exponential backoff strategy with randomized delays and a maximum expiry time of 30,000 milliseconds.

Errors

The function handles errors such as :error, :exit, :noproc, :erpc, :noconnection, and :timeout. It also rescues ErlangError exceptions and logs detailed error messages.

handle_events(events, from, state)

Handles incoming events from the CallerProducer GenStage.

Dispatches events to the appropriate functions for further processing.

init(opts)

Initializes the GenStage consumer.

It subscribes to the CallerProducer GenStage with specified backpressure values.

invoke_with_span(request, opts)

Invokes an actor action with distributed tracing using OpenTelemetry.

This function performs an actor action invocation, incorporating distributed tracing with OpenTelemetry. It sets up the tracing context, adds relevant attributes, and handles asynchronous and synchronous invocations.

Parameters

  • request (%InvocationRequest): The request containing information about the invocation.
  • opts (Keyword.t): Additional options for the invocation. Defaults to an empty keyword list.

Returns

A tuple containing the status and the result of the invocation. If the invocation is asynchronous, it returns {:ok, :async}.

Tracing Context

The function sets up the tracing context and adds attributes related to the invocation. It uses OpenTelemetry to trace the client invoke with the kind set to :client.

Retry Mechanism

The function incorporates a retry mechanism with backoff, randomization, and timeout to handle potential errors during the invocation.

Error Handling

In case of errors during the invocation, appropriate logging and tracing events are added, and the error is re-raised with a stack trace.

liveness(id)

@spec liveness(Spawn.Actors.ActorId.t()) ::
  {:ok, HealthCheckReply.t()} | {:error, any()}

Performs a liveness check for a given actor identified by %ActorId{}.

This function uses a retry mechanism with exponential backoff, randomization, and a 30-second expiry to handle errors and failures gracefully. It attempts to check the liveness of the specified actor, logging any errors encountered during the process.

Parameters

  • id: An %ActorId{} struct that contains:
    • name: The name of the actor.
    • system: The name of the system the actor belongs to.

Returns

  • {:ok, %HealthCheckReply{}} if the liveness check is successful. The HealthCheckReply struct contains:
    • status: A HealthcheckStatus struct with:
      • status: A string indicating the status, e.g., "OK".
      • details: A string providing additional details, e.g., "I'm alive!".
      • updated_at: A Google.Protobuf.Timestamp indicating the last update time.
  • An error tuple (e.g., {:error, :noproc}) if the liveness check fails after all retry attempts.

Examples

iex> liveness(%ActorId{name: "actor1", system: "system1"})
{:ok,
  %HealthCheckReply{
    status: %HealthcheckStatus{
      status: "OK",
      details: "I'm still alive!",
      updated_at: %Google.Protobuf.Timestamp{seconds: 1717606837}
    }
  }}

iex> liveness(%ActorId{name: "nonexistent_actor", system: "system1"})
{:error, :noproc}

Notes

The retry mechanism handles the following cases: :error, :exit, :noproc, :erpc, :noconnection, and :timeout. It rescues only ErlangError.

The liveness check is performed by calling ActorEntity.liveness/2 on the actor reference obtained through do_lookup_action/4.

Any errors during the liveness check are logged with a message indicating the actor's name and the error encountered.

readiness(id)

@spec readiness(Spawn.Actors.ActorId.t()) ::
  {:ok, HealthCheckReply.t()} | {:error, any()}

Performs a readiness check for a given actor identified by %ActorId{}.

This function uses a retry mechanism with exponential backoff, randomization, and a 30-second expiry to handle errors and failures gracefully. It attempts to check the readiness of the specified actor, logging any errors encountered during the process.

Parameters

  • id: An %ActorId{} struct that contains:
    • name: The name of the actor.
    • system: The name of the system the actor belongs to.

Returns

  • {:ok, %HealthCheckReply{}} if the readiness check is successful. The HealthCheckReply struct contains:
    • status: A HealthcheckStatus struct with:
      • status: A string indicating the status, e.g., "OK".
      • details: A string providing additional details, e.g., "I'm alive!".
      • updated_at: A Google.Protobuf.Timestamp indicating the last update time.
  • An error tuple (e.g., {:error, :noproc}) if the readiness check fails after all retry attempts.

Examples

iex> readiness(%ActorId{name: "actor1", system: "system1"})
{:ok,
  %HealthCheckReply{
    status: %HealthcheckStatus{
      status: "OK",
      details: "I'm alive!",
      updated_at: %Google.Protobuf.Timestamp{seconds: 1717606730}
    }
  }}

iex> readiness(%ActorId{name: "nonexistent_actor", system: "system1"})
{:error, :noproc}

Notes

The retry mechanism handles the following cases: :error, :exit, :noproc, :erpc, :noconnection, and :timeout. It rescues only ErlangError.

The readiness check is performed by calling ActorEntity.readiness/2 on the actor reference obtained through do_lookup_action/4.

Any errors during the readiness check are logged with a message indicating the actor's name and the error encountered.

register(registration, opts)

Registers actors in the system based on the provided registration request.

Handles registration requests and ensures actors are properly registered.

spawn_actor(spawn, opts \\ [])

Spawns an actor or a group of actors based on the provided SpawnRequest.

This function is responsible for spawning actors based on the specified SpawnRequest. It retrieves the hosts associated with the provided actor IDs and registers the actors. Additionally, it handles cases where the system is in the process of draining or stopping.

Parameters

  • spawn (%SpawnRequest): The request containing information about the actors to spawn.
  • opts (Keyword.t): Additional options for spawning the actors. Defaults to an empty keyword list.

Returns

If successful, it returns {:ok, %SpawnResponse{status: %RequestStatus{status: :OK, message: "Accepted"}}}. Otherwise, an error is raised.

Actor Spawning Process

  • Retrieves actor hosts based on actor IDs from the ActorRegistry.
  • Filters the hosts based on the system's graceful shutdown status.
  • Registers the selected hosts in the ActorRegistry.
  • Returns a success response.

Errors

  • Raises an ArgumentError if attempting to spawn an unnamed actor that has not been registered before.

start_link(opts \\ [])

Starts the consumer process and subscribes to the CallerProducer GenStage.

try_reactivate_actor(system, actor, opts \\ [])

@spec try_reactivate_actor(
  Spawn.Actors.ActorSystem.t(),
  Spawn.Actors.Actor.t(),
  any()
) ::
  {:ok, any()} | {:error, any()}

Tries to reactivate an actor.

Reactivation is attempted by looking up the actor in the registry or creating a new actor if not found.