Skip to main content

protocol_droid/domain/session/
mod.rs

1//! The session aggregate: lifecycle, in-flight requests, cancellation, progress.
2//!
3//! # Everything here is a pure transition
4//!
5//! No clock, no runtime, no I/O. Time arrives as an [`Instant`] read from a
6//! port the application layer owns; a request becomes in-flight because
7//! [`RequestRegistry::register`] was called, and stops being in-flight because
8//! something completed or cancelled it. That is the whole of the domain's
9//! contribution, and keeping it to that is what makes the state machine
10//! testable by a property test rather than by a mock.
11//!
12//! # The `std::sync` in [`cancellation`]
13//!
14//! [`cancellation::CancellationToken`] holds a `Mutex<Vec<Waker>>` and a
15//! `OnceLock`, which is more machinery than a value object. It is here rather
16//! than in `application` for one reason: the in-flight registry has to hold
17//! the token, and a domain aggregate may not reach outward to borrow one. The
18//! state it holds — *has this request been cancelled, and what did the peer
19//! say* — is domain state; the waker list is the standard-library plumbing that
20//! publishes it to whoever is awaiting. No `Waker` is invented by this crate,
21//! and no executor is named: the token is polled by whoever waits on it, so it
22//! works on any runtime, including a test's.
23//!
24//! # Why there is no timer
25//!
26//! The domain knows a request's *budget* and can say when it is spent, because
27//! that is arithmetic over injected instants. What wakes a future when a
28//! deadline passes belongs to the runtime, and the runtime belongs to the
29//! transport adapter. The engine therefore computes expiry and the adapter
30//! races it — the same division that keeps a transaction inside its adapter.
31
32pub mod cancellation;
33pub mod progress;
34pub mod registry;
35pub mod state;
36
37pub use cancellation::Cancelled;
38pub use cancellation::{AbortReason, CancelReason, CancellationToken};
39pub use progress::{ProgressCursor, ProgressToken, ProgressUpdate};
40pub use registry::{
41    CancelOutcome, DuplicateRequest, InFlight, RequestOrigin, RequestRegistry, UnknownRequest,
42};
43pub use state::{Instant, LifecycleError, LifecycleEvent, Session, SessionId, SessionState};