Skip to main content

RuntimeState

Struct RuntimeState 

Source
pub struct RuntimeState {
    pub regions: Arena<RegionRecord>,
    pub tasks: Arena<TaskRecord>,
    pub obligations: Arena<ObligationRecord>,
    pub now: Time,
    pub root_region: Option<RegionId>,
    pub trace: TraceBufferHandle,
    pub metrics: Arc<dyn MetricsProvider>,
    /* private fields */
}
Expand description

The global runtime state.

This is the “Σ” from the formal semantics: Σ = ⟨R, T, O, τ_now⟩

Fields§

§regions: Arena<RegionRecord>

All region records.

§tasks: Arena<TaskRecord>

All task records.

§obligations: Arena<ObligationRecord>

All obligation records.

§now: Time

Current logical time.

§root_region: Option<RegionId>

The root region.

§trace: TraceBufferHandle

Trace buffer for events.

§metrics: Arc<dyn MetricsProvider>

Metrics provider for runtime instrumentation.

Implementations§

Source§

impl RuntimeState

Source

pub fn new() -> Self

Creates a new empty runtime state without a reactor.

This is equivalent to without_reactor() and creates a runtime suitable for Lab mode or pure computation without I/O.

Source

pub fn new_with_metrics(metrics: Arc<dyn MetricsProvider>) -> Self

Creates a new runtime state with an explicit metrics provider.

Source

pub fn with_reactor_and_metrics( reactor: Arc<dyn Reactor>, metrics: Arc<dyn MetricsProvider>, ) -> Self

Creates a runtime state with a real reactor and metrics provider.

The provided reactor will be wrapped in an IoDriver to handle waker dispatch. Use this constructor when you need real I/O support and want to preserve the runtime’s metrics configuration.

§Arguments
  • reactor - The platform-specific reactor (e.g., EpollReactor on Linux)
  • metrics - Metrics provider to attach to the runtime state
§Example
use asupersync::runtime::{RuntimeState, EpollReactor};
use std::sync::Arc;

let reactor = Arc::new(EpollReactor::new()?);
let state = RuntimeState::with_reactor_and_metrics(reactor, Arc::new(NoOpMetrics));
Source

pub fn with_reactor(reactor: Arc<dyn Reactor>) -> Self

Creates a runtime state with a real reactor for production use.

This uses a NoOpMetrics provider by default. Prefer with_reactor_and_metrics if you need custom metrics.

Source

pub fn without_reactor() -> Self

Creates a runtime state without a reactor (Lab mode).

Use this for deterministic testing or pure computation without I/O. This is equivalent to new().

Source

pub fn io_driver(&self) -> Option<&IoDriverHandle>

Returns a reference to the I/O driver handle, if present.

Returns None if the runtime was created without a reactor.

Source

pub fn io_driver_mut(&self) -> Option<MutexGuard<'_, IoDriver>>

Returns a locked guard to the I/O driver, if present.

Returns None if the runtime was created without a reactor.

Source

pub fn io_driver_handle(&self) -> Option<IoDriverHandle>

Returns a cloned handle to the I/O driver, if present.

Returns None if the runtime was created without a reactor.

Source

pub fn timer_driver(&self) -> Option<&TimerDriverHandle>

Returns a reference to the timer driver handle, if present.

Returns None if the runtime was created without a timer driver.

Source

pub fn timer_driver_handle(&self) -> Option<TimerDriverHandle>

Returns a cloned handle to the timer driver, if present.

Returns None if the runtime was created without a timer driver.

Source

pub fn blocking_pool_handle(&self) -> Option<BlockingPoolHandle>

Returns a cloned handle to the blocking pool, if present.

Source

pub fn set_blocking_pool(&mut self, handle: BlockingPoolHandle)

Sets the blocking pool handle for this runtime.

Source

pub fn set_timer_driver(&mut self, driver: TimerDriverHandle)

Sets the timer driver for this runtime.

Source

pub fn logical_clock_mode(&self) -> &LogicalClockMode

Returns the logical clock mode for new task contexts.

Source

pub fn set_logical_clock_mode(&mut self, mode: LogicalClockMode)

Sets the logical clock mode for new task contexts.

Source

pub fn cancel_attribution_config(&self) -> CancelAttributionConfig

Returns the cancel attribution configuration for this runtime.

Source

pub fn set_cancel_attribution_config(&mut self, config: CancelAttributionConfig)

Sets the cancel attribution configuration for this runtime.

Source

pub fn entropy_source(&self) -> Arc<dyn EntropySource>

Returns the entropy source for this runtime.

Source

pub fn set_entropy_source(&mut self, source: Arc<dyn EntropySource>)

Sets the entropy source for this runtime.

Source

pub fn set_observability_config(&mut self, config: ObservabilityConfig)

Configures runtime observability for new tasks.

Source

pub fn clear_observability_config(&mut self)

Clears runtime observability configuration.

Source

pub fn set_obligation_leak_response(&mut self, response: ObligationLeakResponse)

Sets the response policy when obligation leaks are detected.

Source

pub fn set_leak_escalation(&mut self, escalation: Option<LeakEscalation>)

Sets the escalation policy for obligation leaks.

Source

pub fn leak_count(&self) -> u64

Returns the cumulative count of obligation leaks.

Source

pub fn trace_handle(&self) -> TraceBufferHandle

Returns a handle to the trace buffer.

Source

pub fn metrics_provider(&self) -> Arc<dyn MetricsProvider>

Returns the metrics provider for this runtime.

Source

pub fn set_metrics_provider(&mut self, provider: Arc<dyn MetricsProvider>)

Sets the metrics provider for this runtime.

Source

pub fn task(&self, task_id: TaskId) -> Option<&TaskRecord>

Returns a shared reference to a task record by ID.

Source

pub fn task_mut(&mut self, task_id: TaskId) -> Option<&mut TaskRecord>

Returns a mutable reference to a task record by ID.

Source

pub fn insert_task(&mut self, record: TaskRecord) -> ArenaIndex

Inserts a new task record into the arena.

Returns the assigned arena index.

Source

pub fn remove_task(&mut self, task_id: TaskId) -> Option<TaskRecord>

Removes a task record from the arena.

Returns the removed record if it existed.

Source

pub fn tasks_iter(&self) -> impl Iterator<Item = (ArenaIndex, &TaskRecord)>

Returns an iterator over all task records.

Source

pub fn tasks_is_empty(&self) -> bool

Returns true if the task arena is empty.

Source

pub fn tasks_arena(&self) -> &Arena<TaskRecord>

Provides direct access to the tasks arena.

Used by intrusive data structures (LocalQueue) that operate on the arena.

Source

pub fn tasks_arena_mut(&mut self) -> &mut Arena<TaskRecord>

Provides mutable access to the tasks arena.

Used by intrusive data structures (LocalQueue) that operate on the arena.

Source

pub fn region(&self, region_id: RegionId) -> Option<&RegionRecord>

Returns a shared reference to a region record by ID.

Source

pub fn region_mut(&mut self, region_id: RegionId) -> Option<&mut RegionRecord>

Returns a mutable reference to a region record by ID.

Source

pub fn has_io_driver(&self) -> bool

Returns true if this runtime has an I/O driver.

Source

pub fn snapshot(&self) -> RuntimeSnapshot

Takes a point-in-time snapshot of the runtime state for debugging or visualization.

The snapshot captures a consistent view of regions, tasks, obligations, and recent trace events. It is designed to be lightweight and serializable.

Source

pub fn create_root_region(&mut self, budget: Budget) -> RegionId

Creates a root region and returns its ID.

Source

pub fn create_child_region( &mut self, parent: RegionId, budget: Budget, ) -> Result<RegionId, RegionCreateError>

Creates a child region under the given parent and returns its ID.

The child’s effective budget is the meet (tightest constraints) of the parent budget and the provided budget.

Source

pub fn set_region_limits( &mut self, region: RegionId, limits: RegionLimits, ) -> bool

Updates admission limits for a region.

Returns false if the region does not exist.

Source

pub fn region_limits(&self, region: RegionId) -> Option<RegionLimits>

Returns the current admission limits for a region.

Source

pub fn create_task<F, T>( &mut self, region: RegionId, budget: Budget, future: F, ) -> Result<(TaskId, TaskHandle<T>), SpawnError>
where F: Future<Output = T> + Send + 'static, T: Send + 'static,

Creates a task and stores its future for polling.

This is the core spawn primitive. It:

  1. Creates a TaskRecord in the specified region
  2. Wraps the future to send its result through a oneshot channel
  3. Stores the wrapped future for the executor to poll
  4. Returns a TaskHandle for awaiting the result
§Arguments
  • region - The region that will own this task
  • budget - The budget for this task
  • future - The future to execute
§Returns

A Result containing (TaskId, TaskHandle) on success, or SpawnError on failure.

§Example
let (task_id, handle) = state.create_task(region, budget, async { 42 })?;
// Later: scheduler.schedule(task_id);
// Even later: let result = handle.join(cx)?;
Source

pub fn create_obligation( &mut self, kind: ObligationKind, holder: TaskId, region: RegionId, description: Option<String>, ) -> Result<ObligationId, Error>

Creates and registers an obligation for the given task and region.

This records the obligation in the registry and emits a trace event. Returns an error if the region is closed or admission limits are reached.

Source

pub fn commit_obligation( &mut self, obligation: ObligationId, ) -> Result<u64, Error>

Marks an obligation as committed and emits a trace event.

Returns the duration the obligation was held (nanoseconds).

Source

pub fn abort_obligation( &mut self, obligation: ObligationId, reason: ObligationAbortReason, ) -> Result<u64, Error>

Marks an obligation as aborted and emits a trace event.

Returns the duration the obligation was held (nanoseconds).

Source

pub fn mark_obligation_leaked( &mut self, obligation: ObligationId, ) -> Result<u64, Error>

Marks an obligation as leaked and emits a trace + error event.

Returns the duration the obligation was held (nanoseconds).

Source

pub fn get_stored_future(&mut self, task_id: TaskId) -> Option<&mut StoredTask>

Gets a mutable reference to a stored future for polling.

Returns None if no future is stored for this task.

Source

pub fn remove_stored_future(&mut self, task_id: TaskId) -> Option<StoredTask>

Removes and returns a stored future.

Called when a task completes to clean up the future storage.

Source

pub fn store_spawned_task(&mut self, task_id: TaskId, stored: StoredTask)

Stores a spawned task’s future for execution.

This is called after Scope::spawn to register the StoredTask with the runtime. The task must already have a TaskRecord created via spawn.

§Arguments
  • task_id - The ID of the task (from the TaskHandle)
  • stored - The StoredTask containing the wrapped future
§Example
let (handle, stored) = scope.spawn(&mut state, &cx, |_| async { 42 })?;
state.store_spawned_task(handle.task_id(), stored);
// Now the executor can poll the task
Source

pub fn next_trace_seq(&self) -> u64

Returns the next trace sequence number and increments it.

Source

pub fn live_task_count(&self) -> usize

Counts live tasks.

Source

pub fn live_region_count(&self) -> usize

Counts live regions.

Source

pub fn pending_obligation_count(&self) -> usize

Counts pending obligations.

Source

pub fn is_quiescent(&self) -> bool

Returns true if the runtime is quiescent (no live work).

A runtime is quiescent when:

  • No live tasks are running
  • No pending obligations exist
  • No I/O sources are registered (if I/O driver is present)
Source

pub fn apply_policy_on_child_outcome<P: Policy<Error = Error>>( &mut self, region: RegionId, child: TaskId, outcome: &Outcome<(), Error>, policy: &P, ) -> (PolicyAction, Vec<(TaskId, u8)>)

Applies the region policy when a child reaches a terminal outcome.

This is the core hook for fail-fast behavior: the policy decides whether siblings should be cancelled.

Returns the policy action taken and a list of tasks that need to be moved to the cancel lane in the scheduler.

Source

pub fn cancel_request( &mut self, region_id: RegionId, reason: &CancelReason, _source_task: Option<TaskId>, ) -> Vec<(TaskId, u8)>

Requests cancellation for a region and all its descendants.

This implements the CANCEL-REQUEST transition from the formal semantics. Cancellation propagates down the region tree:

  • The target region’s cancel_reason is set/strengthened
  • All descendant regions are marked with ParentCancelled
  • All tasks in affected regions are moved to CancelRequested state

Returns a list of (TaskId, priority) pairs for tasks that should be moved to the cancel lane. The caller is responsible for updating the scheduler.

§Arguments
  • region_id - The region to cancel
  • reason - The reason for cancellation
  • source_task - The task that initiated cancellation, if known
§Example
let tasks_to_schedule = state.cancel_request(region, &CancelReason::timeout(), None);
for (task_id, priority) in tasks_to_schedule {
    scheduler.move_to_cancel_lane(task_id, priority);
}
Source

pub fn can_region_finalize(&self, region_id: RegionId) -> bool

Checks if a region can transition to finalization.

A region can finalize when all its tasks and child regions have completed. Returns true if the region has no live work remaining.

Source

pub fn task_completed(&mut self, task_id: TaskId) -> Vec<TaskId>

Notifies that a task has completed.

This checks if the owning region can advance its state. Returns the task’s waiters that should be woken.

Source

pub fn drain_ready_async_finalizers(&mut self) -> Vec<(TaskId, u8)>

Drains async finalizers for regions that are ready to run them.

This runs sync finalizers inline and schedules at most one async finalizer per region (respecting the async barrier).

Source

pub fn register_sync_finalizer<F>(&mut self, region_id: RegionId, f: F) -> bool
where F: FnOnce() + Send + 'static,

Registers a synchronous finalizer for a region.

Finalizers are stored in LIFO order and run when the region transitions to the Finalizing state, after all children have completed.

§Arguments
  • region_id - The region to register the finalizer with
  • f - The synchronous cleanup function
§Returns

true if the finalizer was registered, false if the region doesn’t exist or is not in a state that accepts finalizers.

Source

pub fn register_async_finalizer<F>( &mut self, region_id: RegionId, future: F, ) -> bool
where F: Future<Output = ()> + Send + 'static,

Registers an asynchronous finalizer for a region.

Async finalizers run under a cancel mask to prevent interruption. They are driven to completion with a bounded budget.

§Arguments
  • region_id - The region to register the finalizer with
  • future - The async cleanup future
§Returns

true if the finalizer was registered, false if the region doesn’t exist or is not in a state that accepts finalizers.

Source

pub fn pop_region_finalizer(&mut self, region_id: RegionId) -> Option<Finalizer>

Pops the next finalizer from a region’s finalizer stack.

This is called during the Finalizing phase to get the next cleanup handler to run. Finalizers are returned in LIFO order.

§Returns

The next finalizer to run, or None if all finalizers have been executed.

Source

pub fn region_finalizer_count(&self, region_id: RegionId) -> usize

Returns the number of pending finalizers for a region.

Source

pub fn region_finalizers_empty(&self, region_id: RegionId) -> bool

Returns true if a region has no pending finalizers.

Source

pub fn run_sync_finalizers(&mut self, region_id: RegionId) -> Option<Finalizer>

Runs synchronous finalizers for a region until an async finalizer is encountered or the stack is empty.

This method pops and executes sync finalizers in LIFO order. If an async finalizer is encountered, it is returned immediately (and not executed). The caller must schedule/await the async finalizer before calling this method again to process remaining finalizers.

§Returns

An async finalizer that needs to be scheduled, or None if the stack is empty.

Source

pub fn can_region_complete_close(&self, region_id: RegionId) -> bool

Checks if a region can complete its close sequence.

A region can complete close when:

  1. It’s in the Finalizing state
  2. All finalizers have been executed
  3. All tasks (including those spawned by finalizers) are terminal
  4. All obligations are resolved
§Returns

true if the region can transition to Closed state.

Source

pub fn advance_region_state(&mut self, region_id: RegionId)

Advances the region state machine if possible.

This method checks if the region can transition to the next state in its lifecycle (Closing -> Draining -> Finalizing -> Closed). It drives the transitions automatically when prerequisites (no children, no tasks, etc.) are met.

This should be called whenever a task completes, a child region closes, or an obligation is resolved.

Trait Implementations§

Source§

impl Debug for RuntimeState

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for RuntimeState

Source§

fn default() -> Self

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

impl SnapshotRestore for RuntimeState

Source§

fn restorable_snapshot(&self) -> RestorableSnapshot

Creates a restorable snapshot of the current state.

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> 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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> 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<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more