pub trait OperatorSessionStore: Send + Sync {
// Required methods
fn name(&self) -> &str;
fn put<'life0, 'async_trait>(
&'life0 self,
record: OperatorSessionRecord,
) -> Pin<Box<dyn Future<Output = Result<(), OperatorSessionStoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
sid: &'life1 SessionId,
) -> Pin<Box<dyn Future<Output = Result<(), OperatorSessionStoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn list<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<OperatorSessionRecord>, OperatorSessionStoreError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
}Expand description
Required Methods§
Sourcefn put<'life0, 'async_trait>(
&'life0 self,
record: OperatorSessionRecord,
) -> Pin<Box<dyn Future<Output = Result<(), OperatorSessionStoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn put<'life0, 'async_trait>(
&'life0 self,
record: OperatorSessionRecord,
) -> Pin<Box<dyn Future<Output = Result<(), OperatorSessionStoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert or replace the row for record.sid. Upsert semantics: sids
are freshly minted so a same-sid overwrite only happens on a
deliberate re-put of the same session.
Sourcefn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
sid: &'life1 SessionId,
) -> Pin<Box<dyn Future<Output = Result<(), OperatorSessionStoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
sid: &'life1 SessionId,
) -> Pin<Box<dyn Future<Output = Result<(), OperatorSessionStoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Delete the row for sid. NotFound when no such row exists.
Sourcefn list<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<OperatorSessionRecord>, OperatorSessionStoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<OperatorSessionRecord>, OperatorSessionStoreError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
List the sessions this store can decode, ascending by
joined_at_secs (mint order, stable for deterministic rehydration).
§Contract: per row, not all-or-nothing
A backend that decodes at-rest bytes back into
OperatorSessionRecord must not let one undecodable row fail
the whole call. Such a row is skipped and reported with a
tracing::warn! naming the row and the field that failed; the
intact rows are still returned. An Err from this method therefore
means the backend failed (the file is unreadable, the connection
is gone) — never that one stored session went bad.
This matters because the sole caller is boot-time rehydration, and
its own error path is fatal: an Err here takes mse serve down
and every healthy session with it. Undecodable rows are reachable
in practice — an older build could persist shapes a newer one
rejects (sid: "op-<uuid>" predates the S-<hex> shape) — so
all-or-nothing decoding means one stale row bricks the boot.
Skipping the row rather than defaulting the field is deliberate: a session restored minus a field it was minted with would come back claiming something other than what it is, and would fail later, elsewhere, and quietly. Dropping it is the observable choice.
§Backends that never decode
InMemoryOperatorSessionStore holds live
OperatorSessionRecords, so no row of its can be undecodable and
it never skips anything. That is consistent with the contract, not
an exemption from it: “the sessions this store can decode” is every
session it holds.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".