Skip to main content

ActorSystem

Struct ActorSystem 

Source
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

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub async fn send<T>( &mut self, address: String, msg: <T as Actor>::Message, ) -> Result<(), ActorError>
where T: Actor, <T as Actor>::Message: MaybeCodec,

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).

Source

pub async fn send_without_tx_cache<T>( &self, address: String, msg: <T as Actor>::Message, ) -> Result<(), ActorError>
where T: Actor, <T as Actor>::Message: MaybeCodec,

Cache-bypassing variant of send.

Always issues a fresh FindActor against the loop — useful when you don’t want to retain a mailbox Arc (e.g. one-shot sends) or when you’re calling from &self and the cache mutation isn’t allowed. Same retry policy and the same multi-node routing as send.

Source

pub async fn send_broadcast<T>( &mut self, address_regex: String, msg: <T as Actor>::Message, ) -> Vec<Result<(), ActorError>>
where T: Actor, <T as Actor>::Message: MaybeCodec,

Sends a message to all actors that match the given address regex. Returns one entry per matched local actor.

Source

pub async fn send_broadcast_without_tx_cache<T>( &self, address_regex: String, msg: <T as Actor>::Message, ) -> Vec<Result<(), ActorError>>
where T: Actor, <T as Actor>::Message: MaybeCodec,

Non-cached version of send_broadcast. Same return-shape rules apply.

Source

pub async fn send_and_recv<T>( &mut self, address: String, msg: <T as Actor>::Message, ) -> Result<<T as Actor>::Result, ActorError>
where T: Actor, <T as Actor>::Message: MaybeCodec, <T as Actor>::Result: MaybeCodec,

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:

Source

pub async fn send_and_recv_without_tx_cache<T>( &self, address: String, msg: <T as Actor>::Message, ) -> Result<<T as Actor>::Result, ActorError>
where T: Actor, <T as Actor>::Message: MaybeCodec, <T as Actor>::Result: MaybeCodec,

Cache-bypassing variant of send_and_recv. Same semantics, always issues a fresh FindActor.

Source

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>
where T: Actor, <T as Actor>::Message: MaybeCodec, <T as Actor>::Result: MaybeCodec,

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.

Source

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>
where T: Actor, <T as Actor>::Message: MaybeCodec, <T as Actor>::Result: MaybeCodec,

Cache-bypassing variant of send_and_recv_with_timeout. Same timeout semantics; same cleanup on the cross-node path.

Source

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>
where T: Actor, <T as Actor>::Message: MaybeCodec, <T as Actor>::Result: MaybeCodec,

Spawn a background job that delivers msg to address on the schedule described by JobSpec.

  • subscribe = true sends send_and_recv per iteration and pipes each result through RunJobResult::result_subscriber_rx; false uses fire-and-forget send and returns None for the subscriber.
  • job_id: provide one to address the job later with abort_job/stop_job/resume_job; None generates 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.

Source

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>
where T: Actor, <T as Actor>::Message: MaybeCodec, <T as Actor>::Result: MaybeCodec,

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.

Source

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.

Source

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.

Source

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

Source§

fn clone(&self) -> ActorSystem

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for ActorSystem

Available on non-crate feature multi-node only.
Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> MaybeCodec for T
where T: ?Sized,