pub struct ActorSystem { /* private fields */ }Expand description
Main entry point for spawning, addressing, and messaging actors.
Owns one background task — the actor_system_loop — that holds the
authoritative registry of (actor_type, address) → mailbox mappings.
All public methods funnel through that loop via Self::handler_tx,
which keeps registry mutations strictly sequential.
Clone is cheap: clones share the same handler channel and (under
multi-node) the same InterNodeRuntime. Each clone has its own
cache (a local HashMap of mailboxes for fast resends without
touching the loop), so caching is per-clone, not global.
Under the multi-node feature, an ActorSystem may also carry a
xanq broker connection; send/send_and_recv/run_job automatically
route to the right node based on Address::node.
Implementations§
Source§impl ActorSystem
impl ActorSystem
Sourcepub fn new(channel_size: Option<usize>) -> Self
pub fn new(channel_size: Option<usize>) -> Self
Spin up a new ActorSystem and its backing loop task.
channel_size overrides the default CHANNEL_SIZE (4096) for
the command channel that feeds the loop; None keeps the
default. Returned eagerly — the loop task is already running by
the time this returns.
Sourcepub fn handler_tx(&self) -> Sender<ActorSystemCmd>
pub fn handler_tx(&self) -> Sender<ActorSystemCmd>
Clone of the loop’s command channel.
Lets advanced callers drive the registry directly with
ActorSystemCmd variants — typically to bypass the per-clone TX
cache or to issue several FindActor/FilterAddress lookups
without going through the helper methods. The channel is the same
one all built-in methods use, so commands are interleaved in
arrival order with regular traffic.
Sourcepub async fn filter_address(&self, address_regex: String) -> Vec<String>
pub async fn filter_address(&self, address_regex: String) -> Vec<String>
Snapshot of local actor addresses whose names match address_regex.
Uses * as a wildcard (converted to the (\S+) regex
alternative); the pattern is anchored as ^...$. Returns an empty
vector if the loop drops the response — never panics.
Sourcepub fn restart(&mut self, address_regex: String)
pub fn restart(&mut self, address_regex: String)
Restart every local actor whose name matches address_regex
(* wildcard syntax, same as filter_address).
Fire-and-forget — sends a Restart command and returns. Each
matched actor goes Receiving → Stopping → Restarting → Starting → Receiving via the lifecycle hooks; this method does not wait for
the cycle to complete, so a send immediately after restart may
hit an actor still in Restarting and get ActorError::ActorNotReady
after the system’s retry budget.
Sourcepub fn unregister(&mut self, address_regex: String)
pub fn unregister(&mut self, address_regex: String)
Unregister every local actor whose name matches address_regex
and tear down its task. Fire-and-forget.
Each matched actor receives a kill signal, runs post_stop,
transitions to Terminated, and is removed from the local map.
"*" matches everything — convenient for “kill them all” at
shutdown.
Sourcepub async fn send<T>(
&mut self,
address: String,
msg: <T as Actor>::Message,
) -> Result<(), ActorError>
pub async fn send<T>( &mut self, address: String, msg: <T as Actor>::Message, ) -> Result<(), ActorError>
Fire-and-forget send to a single actor.
Tries the per-clone TX cache first; on miss, asks the loop for the
mailbox via FindActor and (on success) caches it for next time.
If the actor is registered but not yet Receiving, retries up to
10 times with 100 ms sleeps before returning
ActorError::ActorNotReady.
Under multi-node, if address.node != self.node_name the
message is encoded via xancode::Codec and shipped through the
broker as InterNodeMessage::Fire (no retry — broker delivery is
best-effort once accepted).
Sourcepub async fn send_without_tx_cache<T>(
&self,
address: String,
msg: <T as Actor>::Message,
) -> Result<(), ActorError>
pub async fn send_without_tx_cache<T>( &self, address: String, msg: <T as Actor>::Message, ) -> Result<(), ActorError>
Sourcepub async fn send_broadcast<T>(
&mut self,
address_regex: String,
msg: <T as Actor>::Message,
) -> Vec<Result<(), ActorError>>
pub async fn send_broadcast<T>( &mut self, address_regex: String, msg: <T as Actor>::Message, ) -> Vec<Result<(), ActorError>>
Sends a message to all actors that match the given address regex. Returns one entry per matched local actor.
Sourcepub async fn send_broadcast_without_tx_cache<T>(
&self,
address_regex: String,
msg: <T as Actor>::Message,
) -> Vec<Result<(), ActorError>>
pub async fn send_broadcast_without_tx_cache<T>( &self, address_regex: String, msg: <T as Actor>::Message, ) -> Vec<Result<(), ActorError>>
Non-cached version of send_broadcast. Same return-shape rules apply.
Sourcepub async fn send_and_recv<T>(
&mut self,
address: String,
msg: <T as Actor>::Message,
) -> Result<<T as Actor>::Result, ActorError>
pub async fn send_and_recv<T>( &mut self, address: String, msg: <T as Actor>::Message, ) -> Result<<T as Actor>::Result, ActorError>
Request-response send: deliver msg and wait for the handler’s
T::Result.
Uses the TX cache and the same readiness retry policy as
send. On a cross-node address the call goes out as
InterNodeMessage::Call; the response is matched back via the
req_id in the pending-requests map and decoded via
xancode::Codec.
Errors:
ActorError::AddressNotFound/ActorError::ActorNotReadywhen the local lookup fails or the actor never becomes ready.ActorError::MessageTypeMismatchif the handler returns a different concrete type thanT::Result(only possible if you bypass the trait at compile time).ActorError::InterNodeRemote/ActorError::InterNodeDecodefor cross-node failures.
Sourcepub async fn send_and_recv_without_tx_cache<T>(
&self,
address: String,
msg: <T as Actor>::Message,
) -> Result<<T as Actor>::Result, ActorError>
pub async fn send_and_recv_without_tx_cache<T>( &self, address: String, msg: <T as Actor>::Message, ) -> Result<<T as Actor>::Result, ActorError>
Cache-bypassing variant of send_and_recv. Same semantics,
always issues a fresh FindActor.
Sourcepub async fn send_and_recv_with_timeout<T>(
&mut self,
address: String,
msg: <T as Actor>::Message,
timeout: Duration,
) -> Result<<T as Actor>::Result, ActorError>
pub async fn send_and_recv_with_timeout<T>( &mut self, address: String, msg: <T as Actor>::Message, timeout: Duration, ) -> Result<<T as Actor>::Result, ActorError>
send_and_recv with a wall-clock deadline. Returns
ActorError::Timeout if the reply doesn’t arrive within
timeout.
Useful under multi-node where a dead peer would otherwise leave
the call awaiting a response that will never arrive — the
underlying oneshot waiter can only fire when the remote sends a
response back, so there’s no implicit failure detection on the
network path. Applies to the local path too: a slow handle
implementation gets cut off the same way.
Cancellation: when timeout fires the inner future is dropped.
For cross-node calls the dispatcher’s pending-requests entry is
reclaimed via a Drop guard, so a late-arriving response is
silently discarded rather than leaking.
Takes &mut self (unlike the _without_tx_cache variant) because
the wrapped send_and_recv mutates the per-clone TX cache.
Sourcepub async fn send_and_recv_without_tx_cache_with_timeout<T>(
&self,
address: String,
msg: <T as Actor>::Message,
timeout: Duration,
) -> Result<<T as Actor>::Result, ActorError>
pub async fn send_and_recv_without_tx_cache_with_timeout<T>( &self, address: String, msg: <T as Actor>::Message, timeout: Duration, ) -> Result<<T as Actor>::Result, ActorError>
Cache-bypassing variant of send_and_recv_with_timeout. Same
timeout semantics; same cleanup on the cross-node path.
Sourcepub async fn run_job<T>(
&mut self,
address: String,
subscribe: bool,
job: JobSpec,
msg: <T as Actor>::Message,
job_id: Option<String>,
) -> Result<RunJobResult<T>, ActorError>
pub async fn run_job<T>( &mut self, address: String, subscribe: bool, job: JobSpec, msg: <T as Actor>::Message, job_id: Option<String>, ) -> Result<RunJobResult<T>, ActorError>
Spawn a background job that delivers msg to address on the
schedule described by JobSpec.
subscribe = truesendssend_and_recvper iteration and pipes each result throughRunJobResult::result_subscriber_rx;falseuses fire-and-forgetsendand returnsNonefor the subscriber.job_id: provide one to address the job later withabort_job/stop_job/resume_job;Nonegenerates a fresh UUID.
The job loop uses tokio::select! to race the sleep against the
abort/stop/resume channels, so abort/stop are responsive even
mid-sleep. Returns once the actor lookup succeeds and the loop
has been spawned; the loop itself runs until max_iter is
reached, the job is aborted, or — for interval = None — the
single iteration completes.
Under multi-node, a cross-node address spawns an analogous loop
that issues InterNodeMessage::Call/Fire envelopes via the
broker on the same schedule.
Sourcepub async fn run_job_without_tx_cache<T>(
&self,
address: String,
subscribe: bool,
job: JobSpec,
msg: <T as Actor>::Message,
job_id: Option<String>,
) -> Result<RunJobResult<T>, ActorError>
pub async fn run_job_without_tx_cache<T>( &self, address: String, subscribe: bool, job: JobSpec, msg: <T as Actor>::Message, job_id: Option<String>, ) -> Result<RunJobResult<T>, ActorError>
Cache-bypassing variant of run_job. Same semantics; the
resolved mailbox is not inserted into the TX cache, so subsequent
send calls to the same address will issue another FindActor.
Sourcepub async fn abort_job(&self, job_id: String)
pub async fn abort_job(&self, job_id: String)
Abort a running job: signal its loop to exit at the next wait
point (start_at wait, inter-iteration sleep, or during a pause).
The job is removed; subsequent stop_job / resume_job for the
same id are no-ops.
Honored within milliseconds — abort is raced against the loop’s
sleep via tokio::select!, so you don’t wait out the remaining
interval.
Sourcepub async fn stop_job(&self, job_id: String)
pub async fn stop_job(&self, job_id: String)
Pause a running job: the loop finishes the current iteration (if
in flight) and then waits on resume_tx. Pair with resume_job
to continue, or with abort_job to terminate while paused.
Sourcepub async fn resume_job(&self, job_id: String)
pub async fn resume_job(&self, job_id: String)
Resume a stop_job’d job. The loop wakes up and immediately
starts the next iteration’s start_at wait (which is usually
zero by the time you resume).
Trait Implementations§
Source§impl Clone for ActorSystem
impl Clone for ActorSystem
Source§fn clone(&self) -> ActorSystem
fn clone(&self) -> ActorSystem
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more