Proc#
A Proc is the fundamental container for actors in hyperactor. It provides the runtime context for actor execution and determines how messages are routed—both inbound messages arriving at the proc from the network and outbound messages leaving the proc.
Construction#
Create a proc using Proc::new():
pub fn new(proc_id: ProcId, forwarder: BoxedMailboxSender) -> Self
Parameters:
proc_id: The proc’s unique identity (see ProcId)forwarder: ABoxedMailboxSenderthat routes all outbound messages from this proc
The forwarder is the critical routing component for remote delivery - when an actor within this proc sends a message to an actor in another proc, it flows through this forwarder.
Example: Service Proc in Host#
From Host::new():
let router = DialMailboxRouter::new();
let service_proc_id = ProcId::Direct(
frontend_addr.clone(),
"service".to_string()
);
let service_proc = Proc::new(service_proc_id, router.boxed());
Here:
The proc is identified by
ProcId::Direct(frontend_addr, "service")All outbound messages use the
DialMailboxRouteras their forwarderThe router will look up target procs and dial their backend addresses
ProcId: Direct Addressing#
Procs are identified using ProcId::Direct:
ProcId::Direct(ChannelAddr, String)
Example:
let addr: ChannelAddr = "unix:@abc123".parse()?;
let proc_id = ProcId::Direct(addr, "service".to_string());
The proc is addressed by:
The host’s channel address (where it can be reached)
A name identifying the proc within that host
See ProcId for complete details.
Forwarder Integration#
The forwarder determines how messages leave the proc. Typically, a DialMailboxRouter is used to enable dynamic routing to multiple destinations.
Using DialMailboxRouter#
Routes messages by looking up target addresses and dialing connections:
let router = DialMailboxRouter::new();
let proc = Proc::new(proc_id, router.boxed());
When an actor sends a message to another proc, the router:
Looks up the target’s address in its address book
Dials a connection (or reuses a cached one)
Sends the message over that connection
See Routers.
Local Proc Bypass#
When a proc sends a message to an actor in another proc, the message normally flows through the proc’s forwarder to a backend address, where a central routing layer forwards it to the destination proc (see Host for the complete architecture with frontend and backend receivers). For procs running on the same host, this can be optimized: procs can dial each other directly via Unix sockets, bypassing the central routing layer entirely.
Injection point: When a proc manager spawns a new proc, instead of providing a plain backend sender as the forwarder, it wraps it with a local-aware forwarder:
// At proc spawn time, the manager injects a local bypass forwarder:
let backend_sender = MailboxClient::dial(backend_addr);
let proc_forwarder = LocalProcDialer::new(
host_frontend_addr, // Identify local procs by this address
socket_dir, // Directory where procs place Unix sockets
backend_sender, // Fallback for remote procs
);
let proc = Proc::new(proc_id, proc_forwarder.boxed());
The forwarder checks each outbound message: if the destination is a local proc (matching the host’s frontend address), it dials directly via the proc’s Unix socket. Otherwise, it routes through the backend sender:
impl MailboxSender for LocalProcDialer {
fn post_unchecked(&self, envelope: MessageEnvelope, ...) {
if envelope.dest().proc_id() == local_proc_on_this_host {
unix_sender.post_unchecked(envelope, ...) // Direct
} else {
backend_sender.post_unchecked(envelope, ...) // Via host backend
}
}
}
This improves throughput for intra-host communication by reducing message copies and preventing the host agent from becoming a sequencing bottleneck for all messages between local procs, while maintaining compatibility with remote routing.
See hyperactor_mesh::bootstrap::mailbox::LocalProcDialer for the implementation.
Spawning Actors#
Once you have a proc, spawn actors within it:
let actor_handle = proc.spawn("my_actor", MyActor::new())?;
The spawned actor:
Runs within this proc
Inherits the proc’s
ProcIdas part of itsActorIdUses the proc’s forwarder for outbound messages
See RemoteSpawn for spawning details.