Skip to main content

Scope

Struct Scope 

Source
pub struct Scope<'r, P: Policy = FailFast> { /* private fields */ }
Expand description

A scope for spawning work within a region.

The scope provides methods for:

  • Spawning tasks
  • Creating child regions
  • Registering finalizers
  • Cancelling all children

Implementations§

Source§

impl<P: Policy> Scope<'_, P>

Source

pub fn spawn_actor<A: Actor>( &self, state: &mut RuntimeState, cx: &Cx, actor: A, mailbox_capacity: usize, ) -> Result<(ActorHandle<A>, StoredTask), SpawnError>

Spawns a new actor in this scope with the given mailbox capacity.

The actor runs as a region-owned task. Messages are delivered through a bounded MPSC channel with two-phase send semantics.

§Arguments
  • state - Runtime state for task creation
  • cx - Capability context
  • actor - The actor instance
  • mailbox_capacity - Bounded mailbox size
§Returns

A tuple of (ActorHandle, StoredTask). The StoredTask must be registered with the runtime via state.store_spawned_task().

Source

pub fn spawn_supervised_actor<A, F>( &self, state: &mut RuntimeState, cx: &Cx, factory: F, strategy: SupervisionStrategy, mailbox_capacity: usize, ) -> Result<(ActorHandle<A>, StoredTask), SpawnError>
where A: Actor, F: FnMut() -> A + Send + 'static,

Spawns a supervised actor with explicit supervision semantics.

Unlike spawn_actor, this method takes a factory closure that can produce new actor instances for restarts. The mailbox persists across restarts, so messages sent while a restartable failure is being handled are buffered for the next instance.

Because Actor has no explicit error return channel, supervised crashes are treated as restartable failures when the strategy is crate::supervision::SupervisionStrategy::Restart. If supervision ultimately stops or escalates, the original panic payload is still surfaced as JoinError::Panicked.

§Arguments
  • state - Runtime state for task creation
  • cx - Capability context
  • factory - Closure that creates actor instances (called on each restart)
  • strategy - Supervision strategy (Stop, Restart, Escalate)
  • mailbox_capacity - Bounded mailbox size
Source§

impl<P: Policy> Scope<'_, P>

Source

pub fn region_id(&self) -> RegionId

Returns the region ID for this scope.

Source

pub fn budget(&self) -> Budget

Returns the budget for this scope.

Source

pub fn capability_budget(&self) -> CapabilityBudget

Returns the capability/resource budget for this scope.

Source

pub fn spawn_registered<F, Fut, Caps>( &self, state: &mut RuntimeState, cx: &Cx<Caps>, f: F, ) -> Result<TaskHandle<Fut::Output>, SpawnError>
where Caps: HasSpawn + Send + Sync + 'static, F: FnOnce(Cx<Caps>) -> Fut + Send + 'static, Fut: Future + Send + 'static, Fut::Output: Send + 'static,

Spawns a task and registers it synchronously with the runtime state.

This legacy state-threaded path combines spawn() with RuntimeState::store_spawned_task() and returns a canonical task id immediately. Keep it for synchronous boot/test paths that must inspect the task record before scheduler admission. Runtime-wired call sites that do not require inline start-failure observation should use Cx::spawn_registered_in, which registers through the v2 spawn gateway without passing &mut RuntimeState.

§Arguments
  • state - The runtime state (for immediate task storage)
  • cx - The capability context (for creating child context)
  • f - A closure that produces the future, receiving the new task’s Cx
§Returns

A TaskHandle<T> for awaiting the task’s result.

§Example
let handle = scope.spawn_registered(&mut state, &cx, |cx| async move {
    cx.trace("Child task running");
    compute_value().await
})?;

let result = handle.join(&cx).await?;
Source

pub async fn region<P2, F, Fut, T, Caps>( &self, state: &mut RuntimeState, cx: &Cx<Caps>, policy: P2, f: F, ) -> Result<Outcome<T, P2::Error>, RegionCreateError>
where P2: Policy, F: FnOnce(Scope<'_, P2>, &mut RuntimeState) -> Fut, Fut: Future<Output = Outcome<T, P2::Error>>,

Creates a child region and runs the provided future within a child scope.

The child region inherits the parent’s budget by default. Use Scope::region_with_budget to tighten constraints for the child.

The returned outcome is the result of the body future. After the body completes, the child region begins its close sequence and advances until it can close (assuming all child tasks have completed and obligations are resolved).

§Errors

Returns RegionCreateError if the parent is closed, missing, or at capacity.

Source

pub async fn region_with_budget<P2, F, Fut, T, Caps>( &self, state: &mut RuntimeState, _cx: &Cx<Caps>, budget: Budget, _policy: P2, f: F, ) -> Result<Outcome<T, P2::Error>, RegionCreateError>
where P2: Policy, F: FnOnce(Scope<'_, P2>, &mut RuntimeState) -> Fut, Fut: Future<Output = Outcome<T, P2::Error>>,

Creates a child region with an explicit budget (met with the parent budget).

The effective budget is parent.meet(child) to ensure nested scopes can never relax constraints.

Source

pub async fn region_with_priority<P2, F, Fut, T, Caps>( &self, state: &mut RuntimeState, _cx: &Cx<Caps>, priority: RegionPriority, _policy: P2, f: F, ) -> Result<Outcome<T, P2::Error>, RegionCreateError>
where P2: Policy, F: FnOnce(Scope<'_, P2>, &mut RuntimeState) -> Fut, Fut: Future<Output = Outcome<T, P2::Error>>,

Creates a child region with an explicit resource-pressure priority.

The child inherits this scope’s scheduler and capability budgets while classifying the admission request before pressure checks run.

Source

pub async fn region_with_budget_and_priority<P2, F, Fut, T, Caps>( &self, state: &mut RuntimeState, _cx: &Cx<Caps>, budget: Budget, priority: RegionPriority, _policy: P2, f: F, ) -> Result<Outcome<T, P2::Error>, RegionCreateError>
where P2: Policy, F: FnOnce(Scope<'_, P2>, &mut RuntimeState) -> Fut, Fut: Future<Output = Outcome<T, P2::Error>>,

Creates a child region with explicit scheduler budget and pressure priority.

Source

pub async fn region_with_budget_and_capability_budget<P2, F, Fut, T, Caps>( &self, state: &mut RuntimeState, _cx: &Cx<Caps>, budget: Budget, capability_budget: CapabilityBudget, requirements: CapabilityBudgetRequirements, _policy: P2, f: F, ) -> Result<Outcome<T, P2::Error>, RegionCreateError>
where P2: Policy, F: FnOnce(Scope<'_, P2>, &mut RuntimeState) -> Fut, Fut: Future<Output = Outcome<T, P2::Error>>,

Creates a child region with explicit scheduler and capability budgets.

Both budgets inherit from the parent scope and can only be tightened by the child-supplied envelopes. Required capability dimensions fail closed if neither the parent nor child supplies a non-exhausted envelope.

Source

pub async fn join<T1, T2>( &self, cx: &Cx, h1: TaskHandle<T1>, h2: TaskHandle<T2>, ) -> (Result<T1, JoinError>, Result<T2, JoinError>)

Joins two tasks, waiting for both to complete.

This method waits for both tasks to complete, regardless of their outcome. It returns a tuple of results.

§Example
let h1 = scope.spawn_registered(...);
let h2 = scope.spawn_registered(...);
let (r1, r2) = scope.join(cx, h1, h2).await;
Source

pub async fn race<T>( &self, cx: &Cx, h1: TaskHandle<T>, h2: TaskHandle<T>, ) -> Result<T, JoinError>

Races two task handles and returns the winner while draining the loser.

Source

pub async fn hedge<F1, Fut1, F2, Fut2, T>( &self, state: &mut RuntimeState, cx: &Cx, delay: Duration, primary: F1, backup: F2, ) -> Result<T, JoinError>
where F1: FnOnce(Cx) -> Fut1 + Send + 'static, Fut1: Future<Output = T> + Send + 'static, F2: FnOnce(Cx) -> Fut2 + Send + 'static, Fut2: Future<Output = T> + Send + 'static, T: Send + 'static,

Hedges a primary operation with a backup operation.

  1. Spawns the primary task immediately.
  2. Waits for the delay.
  3. If primary finishes before delay: returns primary result.
  4. If delay fires: spawns backup task and races them.

The loser is cancelled and drained.

§Arguments
  • state - The runtime state
  • cx - The capability context
  • delay - The hedge delay
  • primary - The primary future factory
  • backup - The backup future factory
§Returns

Ok(T) if successful, Err(JoinError) if failed/cancelled.

Source

pub async fn race_all<T>( &self, cx: &Cx, handles: Vec<TaskHandle<T>>, ) -> Result<(T, usize), JoinError>

Races multiple tasks, waiting for the first to complete.

The winner’s result is returned. Losers are cancelled and drained.

§Arguments
  • cx - The capability context
  • handles - Vector of task handles to race
§Returns

Ok((value, index)) if the winner succeeded. Err(e) if the winner failed (error/cancel/panic).

Source

pub async fn join_all<T>( &self, cx: &Cx, handles: Vec<TaskHandle<T>>, ) -> Vec<Result<T, JoinError>>

Joins multiple tasks, waiting for all to complete.

Returns a vector of results in the same order as the input handles.

Source

pub fn defer_sync<F>(&self, state: &mut RuntimeState, f: F) -> bool
where F: FnOnce() + Send + 'static,

Registers a synchronous finalizer to run when the region closes.

Finalizers are stored in LIFO order and executed during the Finalizing phase, after all children have completed. Use this for lightweight cleanup that doesn’t need to await.

§Arguments
  • state - The runtime state
  • f - The synchronous cleanup function
§Returns

true if the finalizer was registered successfully.

§Example
scope.defer_sync(&mut state, || {
    println!("Cleaning up!");
});
Source

pub fn defer_async<F>(&self, state: &mut RuntimeState, future: F) -> bool
where F: Future<Output = ()> + Send + 'static,

Registers an asynchronous finalizer to run when the region closes.

Async finalizers run under a cancel mask to prevent interruption. They are driven to completion with a bounded budget. Use this for cleanup that needs to perform async operations (e.g., closing connections, flushing buffers).

§Arguments
  • state - The runtime state
  • future - The async cleanup future
§Returns

true if the finalizer was registered successfully.

§Example
scope.defer_async(&mut state, async {
    close_connection().await;
});
Source§

impl<P: Policy> Scope<'_, P>

Source

pub fn spawn_gen_server<S: GenServer>( &self, state: &mut RuntimeState, cx: &Cx, server: S, mailbox_capacity: usize, ) -> Result<(GenServerHandle<S>, StoredTask), SpawnError>

Spawns a new GenServer in this scope.

The server runs as a region-owned task. Calls and casts are delivered through a bounded MPSC channel with two-phase send semantics.

Source

pub fn spawn_named_gen_server<S: GenServer>( &self, state: &mut RuntimeState, cx: &Cx, registry: &mut NameRegistry, name: impl Into<String>, server: S, mailbox_capacity: usize, now: Time, ) -> Result<(NamedGenServerHandle<S>, StoredTask), NamedSpawnError>

Spawns a named GenServer in this scope, registering it in the given [NameRegistry].

This combines spawn_gen_server with [NameRegistry::register] into a single atomic operation: the name is acquired after the server task is created but before it starts processing messages.

On success, the returned NamedGenServerHandle holds both the server handle and the name lease. The lease is resolved when the handle is released via NamedGenServerHandle::release_name or aborted via NamedGenServerHandle::abort_lease.

§Errors

Returns NamedSpawnError::Spawn if the underlying task spawn fails, or NamedSpawnError::NameTaken if the name is already registered. In the name-taken case, the server task is not spawned (it is abandoned before being stored).

Trait Implementations§

Source§

impl<P: Policy> Debug for Scope<'_, P>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'r, P> Freeze for Scope<'r, P>

§

impl<'r, P> RefUnwindSafe for Scope<'r, P>
where P: RefUnwindSafe,

§

impl<'r, P> Send for Scope<'r, P>

§

impl<'r, P> Sync for Scope<'r, P>

§

impl<'r, P> Unpin for Scope<'r, P>

§

impl<'r, P> UnsafeUnpin for Scope<'r, P>

§

impl<'r, P> UnwindSafe for Scope<'r, P>
where P: RefUnwindSafe,

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, _span: NoopSpan) -> Self

Instruments this future with a span (no-op when disabled).
Source§

fn in_current_span(self) -> Self

Instruments this future with the current span (no-op when disabled).
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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V