Skip to main content

SessionRegistryV2

Struct SessionRegistryV2 

Source
pub struct SessionRegistryV2 { /* private fields */ }
Expand description

Registry that manages the lifecycle of v2 execution sessions.

Clone is cheap — the inner Arc<RwLock<...>> is reference-counted.

Implementations§

Source§

impl SessionRegistryV2

Source

pub fn new( executor: Arc<Executor>, state_store: Arc<JsonFileStore>, card_store: Arc<FileCardStore>, scenarios_dir: PathBuf, ) -> Self

Create a new empty registry backed by executor, with the storage paths that will be injected into each spawned VM session.

The state_store / card_store / scenarios_dir mirror the legacy AppService resolution against the AppConfig::app_dir() layout, so a v2 caller produces the same on-disk side effects as a legacy caller.

Source

pub async fn spawn_v2(&self, spec: SessionSpec) -> Result<SessionId, SpawnError>

Start a new v2 execution session, returning the SessionId immediately.

Execution proceeds in the background via tokio::spawn(driver_loop(...)). The caller receives the SessionId without waiting for execution to complete or for the first event (Invariant 6 / debt #40955).

Only algocline_core::execution::SpecKind::Run is supported in this subtask. Other variants return SpawnError::InvalidSpec. Subtask 3 will extend this to handle Advice and Eval through the full AppService path.

§Errors
Source

pub async fn state(&self, id: &SessionId) -> Result<ExecutionState, StateError>

Query the current ExecutionState of a session.

§Errors
Source

pub async fn resume( &self, id: &SessionId, payload: ResumePayload, ) -> Result<ResumeOutcome, ResumeError>

Resume a paused session by delivering LLM responses.

§Errors
Source

pub async fn cancel( &self, id: &SessionId, reason: CancelReason, ) -> Result<(), CancelError>

Request cooperative cancellation of a session.

Idempotent: returns Ok(()) for sessions already in a terminal state.

§Errors
Source

pub fn observe( &self, id: &SessionId, ) -> Result<Box<dyn ObserverHandle>, ObserveError>

Subscribe to the progress event stream for a session.

This is a synchronous fn: broadcast::Sender::subscribe() is synchronous and does not perform I/O. Multiple concurrent subscribers each receive the full event stream independently (Crux R3).

§Errors
  • ObserveError::NotFound — no session with the given id exists, or try_read() experienced lock contention (write lock held by spawn). The contention path emits tracing::warn!(target = "session.observe", ...); callers cannot distinguish it from a true absent-session result.
Source

pub async fn await_terminal( &self, id: &SessionId, ) -> Result<TerminalOutcome, AwaitError>

Await the terminal state of a session.

Polls the shared state until it reaches a terminal variant (Done, Cancelled, or Failed). The JoinHandle is never .abort()-ed (Crux R2).

§Errors
Source

pub fn spawn_gc_task(&self, ttl: Duration, interval: Duration)

Spawn a background GC task that periodically evicts idle, terminal sessions.

Mirrors the legacy SessionRegistry::spawn_gc_task contract (Crux #3 legacy parity) with two extensions:

  1. Subscriber-count gate (Crux #1): a session is only evicted when bus_tx.receiver_count() == 0 at the moment the write guard is held, ensuring no use-after-eviction for active observers.
  2. Parameterised interval (Crux #2): callers can supply a sub-second interval for test determinism without requiring tokio::time::pause.

The JoinHandle returned by tokio::spawn is intentionally dropped — the task runs until process exit (legacy fire-and-forget contract).

§K-4 invariant

The sessions write guard is acquired once per GC tick. All operations inside the guard (receiver_count(), AtomicI64::load, HashMap::remove) are synchronous — no .await is called while the guard is held.

Trait Implementations§

Source§

impl Clone for SessionRegistryV2

Source§

fn clone(&self) -> SessionRegistryV2

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

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

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> MaybeSend for T
where T: Send,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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