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: TimeCurrent logical time.
root_region: Option<RegionId>The root region.
trace: TraceBufferHandleTrace buffer for events.
metrics: Arc<dyn MetricsProvider>Metrics provider for runtime instrumentation.
Implementations§
Source§impl RuntimeState
impl RuntimeState
Sourcepub fn new() -> Self
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.
Sourcepub fn new_with_metrics(metrics: Arc<dyn MetricsProvider>) -> Self
pub fn new_with_metrics(metrics: Arc<dyn MetricsProvider>) -> Self
Creates a new runtime state with an explicit metrics provider.
Sourcepub fn with_reactor_and_metrics(
reactor: Arc<dyn Reactor>,
metrics: Arc<dyn MetricsProvider>,
) -> Self
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.,EpollReactoron 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));Sourcepub fn with_reactor(reactor: Arc<dyn Reactor>) -> Self
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.
Sourcepub fn without_reactor() -> Self
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().
Sourcepub fn io_driver(&self) -> Option<&IoDriverHandle>
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.
Sourcepub fn io_driver_mut(&self) -> Option<MutexGuard<'_, IoDriver>>
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.
Sourcepub fn io_driver_handle(&self) -> Option<IoDriverHandle>
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.
Sourcepub fn timer_driver(&self) -> Option<&TimerDriverHandle>
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.
Sourcepub fn timer_driver_handle(&self) -> Option<TimerDriverHandle>
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.
Sourcepub fn blocking_pool_handle(&self) -> Option<BlockingPoolHandle>
pub fn blocking_pool_handle(&self) -> Option<BlockingPoolHandle>
Returns a cloned handle to the blocking pool, if present.
Sourcepub fn set_blocking_pool(&mut self, handle: BlockingPoolHandle)
pub fn set_blocking_pool(&mut self, handle: BlockingPoolHandle)
Sets the blocking pool handle for this runtime.
Sourcepub fn set_timer_driver(&mut self, driver: TimerDriverHandle)
pub fn set_timer_driver(&mut self, driver: TimerDriverHandle)
Sets the timer driver for this runtime.
Sourcepub fn logical_clock_mode(&self) -> &LogicalClockMode
pub fn logical_clock_mode(&self) -> &LogicalClockMode
Returns the logical clock mode for new task contexts.
Sourcepub fn set_logical_clock_mode(&mut self, mode: LogicalClockMode)
pub fn set_logical_clock_mode(&mut self, mode: LogicalClockMode)
Sets the logical clock mode for new task contexts.
Sourcepub fn cancel_attribution_config(&self) -> CancelAttributionConfig
pub fn cancel_attribution_config(&self) -> CancelAttributionConfig
Returns the cancel attribution configuration for this runtime.
Sourcepub fn set_cancel_attribution_config(&mut self, config: CancelAttributionConfig)
pub fn set_cancel_attribution_config(&mut self, config: CancelAttributionConfig)
Sets the cancel attribution configuration for this runtime.
Sourcepub fn entropy_source(&self) -> Arc<dyn EntropySource>
pub fn entropy_source(&self) -> Arc<dyn EntropySource>
Returns the entropy source for this runtime.
Sourcepub fn set_entropy_source(&mut self, source: Arc<dyn EntropySource>)
pub fn set_entropy_source(&mut self, source: Arc<dyn EntropySource>)
Sets the entropy source for this runtime.
Sourcepub fn set_observability_config(&mut self, config: ObservabilityConfig)
pub fn set_observability_config(&mut self, config: ObservabilityConfig)
Configures runtime observability for new tasks.
Sourcepub fn clear_observability_config(&mut self)
pub fn clear_observability_config(&mut self)
Clears runtime observability configuration.
Sourcepub fn set_obligation_leak_response(&mut self, response: ObligationLeakResponse)
pub fn set_obligation_leak_response(&mut self, response: ObligationLeakResponse)
Sets the response policy when obligation leaks are detected.
Sourcepub fn set_leak_escalation(&mut self, escalation: Option<LeakEscalation>)
pub fn set_leak_escalation(&mut self, escalation: Option<LeakEscalation>)
Sets the escalation policy for obligation leaks.
Sourcepub fn leak_count(&self) -> u64
pub fn leak_count(&self) -> u64
Returns the cumulative count of obligation leaks.
Sourcepub fn trace_handle(&self) -> TraceBufferHandle
pub fn trace_handle(&self) -> TraceBufferHandle
Returns a handle to the trace buffer.
Sourcepub fn metrics_provider(&self) -> Arc<dyn MetricsProvider>
pub fn metrics_provider(&self) -> Arc<dyn MetricsProvider>
Returns the metrics provider for this runtime.
Sourcepub fn set_metrics_provider(&mut self, provider: Arc<dyn MetricsProvider>)
pub fn set_metrics_provider(&mut self, provider: Arc<dyn MetricsProvider>)
Sets the metrics provider for this runtime.
Sourcepub fn task(&self, task_id: TaskId) -> Option<&TaskRecord>
pub fn task(&self, task_id: TaskId) -> Option<&TaskRecord>
Returns a shared reference to a task record by ID.
Sourcepub fn task_mut(&mut self, task_id: TaskId) -> Option<&mut TaskRecord>
pub fn task_mut(&mut self, task_id: TaskId) -> Option<&mut TaskRecord>
Returns a mutable reference to a task record by ID.
Sourcepub fn insert_task(&mut self, record: TaskRecord) -> ArenaIndex
pub fn insert_task(&mut self, record: TaskRecord) -> ArenaIndex
Inserts a new task record into the arena.
Returns the assigned arena index.
Sourcepub fn remove_task(&mut self, task_id: TaskId) -> Option<TaskRecord>
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.
Sourcepub fn tasks_iter(&self) -> impl Iterator<Item = (ArenaIndex, &TaskRecord)>
pub fn tasks_iter(&self) -> impl Iterator<Item = (ArenaIndex, &TaskRecord)>
Returns an iterator over all task records.
Sourcepub fn tasks_is_empty(&self) -> bool
pub fn tasks_is_empty(&self) -> bool
Returns true if the task arena is empty.
Sourcepub fn tasks_arena(&self) -> &Arena<TaskRecord>
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.
Sourcepub fn tasks_arena_mut(&mut self) -> &mut Arena<TaskRecord>
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.
Sourcepub fn region(&self, region_id: RegionId) -> Option<&RegionRecord>
pub fn region(&self, region_id: RegionId) -> Option<&RegionRecord>
Returns a shared reference to a region record by ID.
Sourcepub fn region_mut(&mut self, region_id: RegionId) -> Option<&mut RegionRecord>
pub fn region_mut(&mut self, region_id: RegionId) -> Option<&mut RegionRecord>
Returns a mutable reference to a region record by ID.
Sourcepub fn has_io_driver(&self) -> bool
pub fn has_io_driver(&self) -> bool
Returns true if this runtime has an I/O driver.
Sourcepub fn snapshot(&self) -> RuntimeSnapshot
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.
Sourcepub fn create_root_region(&mut self, budget: Budget) -> RegionId
pub fn create_root_region(&mut self, budget: Budget) -> RegionId
Creates a root region and returns its ID.
Sourcepub fn create_child_region(
&mut self,
parent: RegionId,
budget: Budget,
) -> Result<RegionId, RegionCreateError>
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.
Sourcepub fn set_region_limits(
&mut self,
region: RegionId,
limits: RegionLimits,
) -> bool
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.
Sourcepub fn region_limits(&self, region: RegionId) -> Option<RegionLimits>
pub fn region_limits(&self, region: RegionId) -> Option<RegionLimits>
Returns the current admission limits for a region.
Sourcepub fn create_task<F, T>(
&mut self,
region: RegionId,
budget: Budget,
future: F,
) -> Result<(TaskId, TaskHandle<T>), SpawnError>
pub fn create_task<F, T>( &mut self, region: RegionId, budget: Budget, future: F, ) -> Result<(TaskId, TaskHandle<T>), SpawnError>
Creates a task and stores its future for polling.
This is the core spawn primitive. It:
- Creates a TaskRecord in the specified region
- Wraps the future to send its result through a oneshot channel
- Stores the wrapped future for the executor to poll
- Returns a TaskHandle for awaiting the result
§Arguments
region- The region that will own this taskbudget- The budget for this taskfuture- 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)?;Sourcepub fn create_obligation(
&mut self,
kind: ObligationKind,
holder: TaskId,
region: RegionId,
description: Option<String>,
) -> Result<ObligationId, Error>
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.
Sourcepub fn commit_obligation(
&mut self,
obligation: ObligationId,
) -> Result<u64, Error>
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).
Sourcepub fn abort_obligation(
&mut self,
obligation: ObligationId,
reason: ObligationAbortReason,
) -> Result<u64, Error>
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).
Sourcepub fn mark_obligation_leaked(
&mut self,
obligation: ObligationId,
) -> Result<u64, Error>
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).
Sourcepub fn get_stored_future(&mut self, task_id: TaskId) -> Option<&mut StoredTask>
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.
Sourcepub fn remove_stored_future(&mut self, task_id: TaskId) -> Option<StoredTask>
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.
Sourcepub fn store_spawned_task(&mut self, task_id: TaskId, stored: StoredTask)
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 taskSourcepub fn next_trace_seq(&self) -> u64
pub fn next_trace_seq(&self) -> u64
Returns the next trace sequence number and increments it.
Sourcepub fn live_task_count(&self) -> usize
pub fn live_task_count(&self) -> usize
Counts live tasks.
Sourcepub fn live_region_count(&self) -> usize
pub fn live_region_count(&self) -> usize
Counts live regions.
Sourcepub fn pending_obligation_count(&self) -> usize
pub fn pending_obligation_count(&self) -> usize
Counts pending obligations.
Sourcepub fn is_quiescent(&self) -> bool
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)
Sourcepub 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)>)
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.
Sourcepub fn cancel_request(
&mut self,
region_id: RegionId,
reason: &CancelReason,
_source_task: Option<TaskId>,
) -> Vec<(TaskId, u8)>
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
CancelRequestedstate
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 cancelreason- The reason for cancellationsource_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);
}Sourcepub fn can_region_finalize(&self, region_id: RegionId) -> bool
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.
Sourcepub fn task_completed(&mut self, task_id: TaskId) -> Vec<TaskId>
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.
Sourcepub fn drain_ready_async_finalizers(&mut self) -> Vec<(TaskId, u8)>
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).
Sourcepub fn register_sync_finalizer<F>(&mut self, region_id: RegionId, f: F) -> bool
pub fn register_sync_finalizer<F>(&mut self, region_id: RegionId, f: F) -> bool
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 withf- 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.
Sourcepub fn register_async_finalizer<F>(
&mut self,
region_id: RegionId,
future: F,
) -> bool
pub fn register_async_finalizer<F>( &mut self, region_id: RegionId, future: F, ) -> bool
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 withfuture- 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.
Sourcepub fn pop_region_finalizer(&mut self, region_id: RegionId) -> Option<Finalizer>
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.
Sourcepub fn region_finalizer_count(&self, region_id: RegionId) -> usize
pub fn region_finalizer_count(&self, region_id: RegionId) -> usize
Returns the number of pending finalizers for a region.
Sourcepub fn region_finalizers_empty(&self, region_id: RegionId) -> bool
pub fn region_finalizers_empty(&self, region_id: RegionId) -> bool
Returns true if a region has no pending finalizers.
Sourcepub fn run_sync_finalizers(&mut self, region_id: RegionId) -> Option<Finalizer>
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.
Sourcepub fn can_region_complete_close(&self, region_id: RegionId) -> bool
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:
- It’s in the Finalizing state
- All finalizers have been executed
- All tasks (including those spawned by finalizers) are terminal
- All obligations are resolved
§Returns
true if the region can transition to Closed state.
Sourcepub fn advance_region_state(&mut self, region_id: RegionId)
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.