Expand description
Actor interface for remotely spawning actors.
ActorSpawner is a spawn factory actor. A proc that wants to accept
dynamic actor spawns runs an ActorSpawner locally and exposes an
ActorRef<ActorSpawner> to callers, for example through a token
rendezvous. A caller can post SpawnActor directly, but most callers
should use ActorSpawnerEndpoint. The extension trait builds the spawn
request, starts the local supervisor that owns the remote actor lifetime,
and returns the ActorRef for the actor that will be created on the
remote proc.
Spawning through ActorSpawnerEndpoint makes the spawning actor the
supervisor of the spawned remote actor. Logically, the remote actor becomes
part of the spawner’s supervision tree even though it runs on another proc:
caller proc remote proc
caller actor
`- spawned actor A -------- runs on --------> ActorSpawner's procThe implementation realizes that logical edge with a caller-side supervisor, a remote worker, and a cross-proc session. Boxes are actors. Arrow labels are protocol messages.
caller proc remote proc
caller actor
`- [Supervisor] -- SpawnActor ----------------> [ActorSpawner]
`- [Worker]
`- [spawned actor A]
[Supervisor] <-------- SupervisorEvent -------- [Worker]The caller-side Supervisor is spawned as a child of the actor that
requested the remote spawn. Its bootstrap posts SpawnActor to the remote
ActorSpawner. The remote ActorSpawner spawns a Worker child and asks it
to deserialize the Gspawn specification, spawn the requested actor as its
own child, and attach it to the caller-side supervisor. The caller-side
supervisor also owns the private liveness machinery that lets either proc
observe when the other side disappears.
The resulting lifetime is rooted in the caller’s actor tree. If the caller
tree stops, Supervisor forwards a stop request to Worker, and Worker
stops the spawned actor. If the spawned actor fails, Worker reports the
supervision event to Supervisor, which re-raises it into the caller’s
supervision tree. If the supervisor session fails, the surviving side turns
that into a terminal supervision event instead of leaving an orphaned remote
actor.
A typical caller only needs the extension trait. The returned ActorRef
names where the actor will run and is usable immediately: the remote proc
queues messages for the actor until it starts. They are returned as
undeliverable only if the actor does not start within
hyperactor::config::PENDING_ACTOR_DELIVERY_TIMEOUT:
use hyperactor::ActorRef;
use hyperactor::Context;
use hyperactor::Handler;
use hyperactor::Label;
use hyperactor::RemoteSpawn;
use hyperactor::Uid;
use hyperactor_remote::ActorSpawner;
use hyperactor_remote::ActorSpawnerEndpoint;
struct Driver {
actor_spawner: ActorRef<ActorSpawner>,
}
impl Handler<Start> for Driver {
async fn handle(&mut self, cx: &Context<Self>, _start: Start) -> anyhow::Result<()> {
let calculator = self.actor_spawner.spawn_uid::<Calculator>(
cx,
Uid::instance(Label::new("calculator").unwrap()),
CalculatorParams { initial_value: 0 },
)?;
calculator.post(cx, Add { lhs: 40, rhs: 2 });
Ok(())
}
}
Structs§
- Actor
Spawner - Remote actor that accepts dynamic remote spawn requests.
- Spawn
Actor - The generated behavior struct.
Traits§
- Actor
Spawner Endpoint - Convenience methods for endpoints that accept
SpawnActorrequests.