Skip to main content

SessionStore

Struct SessionStore 

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

Thread-safe storage for sessions.

Implementations§

Source§

impl SessionStore

Source

pub fn new() -> Self

Create a new empty session store.

Source

pub fn create(&self) -> Result<SessionId>

Create a new session.

Returns the newly assigned session ID.

Source

pub fn get(&self, id: &SessionId) -> Result<Option<Session>>

Get a clone of the session with the given ID.

Source

pub fn contains(&self, id: &SessionId) -> Result<bool>

Check if a session exists.

Source

pub fn update<F>(&self, id: &SessionId, f: F) -> Result<()>
where F: FnOnce(&mut Session),

Update a session using a closure.

The closure receives a mutable reference to the session and can modify it. Returns an error if the session doesn’t exist.

Source

pub fn remove(&self, id: &SessionId) -> Result<Option<Session>>

Remove a session from the store.

Returns the removed session, or None if it didn’t exist.

Source

pub fn count(&self) -> usize

Get the number of sessions in the store.

Source

pub fn list_ids(&self) -> Result<Vec<SessionId>>

List all session IDs.

Source

pub fn remove_matching<F>(&self, predicate: F) -> Result<usize>
where F: Fn(&Session) -> bool,

Remove all sessions matching a predicate.

Returns the number of sessions removed.

Source

pub fn sweep_idle(&self, ttl: Duration) -> Result<Vec<SessionId>>

Drop sessions that have sat idle past ttl, returning their ids.

Nothing reclaimed a shell session before this: there was no TTL, no cap and no sweeper, and remove_matching had no caller outside tests. A client that creates sessions and never DELETEs them therefore accumulated them for as long as the process ran. Upload sessions have had exactly this — a periodic sweep against fs::SESSION_TTL — since they were introduced; shell sessions simply had no equivalent.

A session running a command is never swept, whatever its idle clock says. That clock is only advanced when a command starts and when it ends (BusySession), so during a long command it does not move at all — idle time alone cannot tell “abandoned” from “busy”, and a sweep keyed on it would reap a session with a command actively running in it. The state is what distinguishes them: the same guard that stops the clock also holds the session Active for the length of the command, and that guard closes every exit including a cancelled future. Active cannot hide an unbounded session either, since a command’s deadline is bounded (execution::MAX_TIMEOUT).

That last sentence is only true while the guard’s life is the command’s life, which is a stronger condition than it sounds. Until 0.21.1 the session WebSocket handler held it across delivery as well, and delivery is bounded by nothing: a consumer that stopped reading its socket parked the handler mid-send, so the session stayed Active — and unsweepable — for as long as that consumer liked. Measured at 75 s on a command that died at its 5 s deadline, ending when the consumer resumed rather than at any deadline at all. A guard that outlives what it claims to track puts this sweep back where it was before there was one.

Ids are returned rather than counted so the caller can record what went; a session vanishing with no trace is what makes an abandoned one indistinguishable from one the client deleted.

Trait Implementations§

Source§

impl Default for SessionStore

Source§

fn default() -> Self

Returns the “default value” for a type. 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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

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<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