Struct retina::client::SessionGroup

source ·
pub struct SessionGroup { /* private fields */ }
Expand description

A group of sessions, currently used only to track stale sessions.

Sessions are associated with a group via SessionOptions::session_group.

This is an experimental API which may change in an upcoming Retina version.

Stale sessions

Stale sessions are ones which are no longer active on the client side (no Session struct exists) but may still be in state Ready, Playing, or Recording on the server. The client has neither seen a TEARDOWN response nor believes they have reached their expiration time. They are tracked in two cases:

  1. Dropped Sessions if the TeardownPolicy says to do so and a valid SETUP response has been received.

    A tokio background task is responsible for attempting a TEARDOWN and cleaning the session after success or expiration. SessionGroup::await_teardown can be used to wait out this process.

    In general, the tracked expiration time is worst-case. The exception is if the sender hasn’t responded to a keepalive request. In that case there’s theoretically no bound on when the server could see the request and extend the session. Retina ignores this possibility.

  2. TCP sessions discovered via unexpected RTSP interleaved data packets. These are assumed to be due to a live555 bug in which data continues to be sent on a stale file descriptor after a connection is closed. The sessions’ packets may be sent to unrelated (even unauthenticated and/or non-RTSP!) connections after the file descriptor is reused. These sessions may have been started by a process unknown to us and their session id is unknown, so in general it is not possible to send a TEARDOWN.

    These sessions are assumed to expire 65 seconds after discovery, a constant taken from old live555 code.

Granularity

A SessionGroup can be of any granularity, but a typical use is to ensure there are no stale sessions before starting a fresh session (see SessionGroup::stale_sessions and SessionGroup::await_stale_sessions). Groups should be sized to match that idea. If connecting to a live555 server affected by the stale TCP session bug, it might be wise to have one group per server, so that all such sessions can be drained before initiating new connections. Otherwise it might be useful to have one group per describe URL (potentially several per server) and have at most one active session per URL.

Implementations§

source§

impl SessionGroup

source

pub fn named(self, name: String) -> Self

Returns this group with an assigned name.

Typically called before placing into an Arc, e.g. Arc::new(SessionGroup::default().named("foo")).

source

pub fn name(&self) -> Option<&str>

Returns the name of this session group, if any.

source

pub fn stale_sessions(&self) -> StaleSessionStatus

Returns the status of stale sessions in this group.

Currently this only returns information about sessions which may be in state Playing. That is, ones for which Retina has either sent a PLAY request (regardless of whether it received a response) or discovered as described in SessionGroup.

The caller might use this in a loop with await_stale_sessions to sleep until there are no such sessions, logging updates

source

pub async fn await_teardown(&self) -> Result<(), Error>

Waits for a reasonable attempt at TEARDOWN on all stale sessions that exist as of when this method is called, returning an error if any session’s reasonable attempts fail.

This has no timeout other than the sessions’ expiration times. The caller can wrap the call in tokio::time::timeout for an earlier time.

Currently on Session::drop, a TEARDOWN loop is started in the background. This method waits for an attempt on an existing connection (if any) and in some cases the first attempt on a fresh connection. Retina may continue sending more attempts even after this method returns.

Ignores the discovered live555 bug sessions, as it’s impossible to send a TEARDOWN without knowing the session id. If desired, the caller can learn of the existence of the sessions through SessionGroup::stale_sessions and sleep until they expire.

Panics

If the TEARDOWN was initiated from a tokio runtime which has since shut down.

source

pub async fn await_stale_sessions(&self, status: &StaleSessionStatus)

Waits for all of the sessions described by status to expire or be torn down.

Trait Implementations§

source§

impl Default for SessionGroup

source§

fn default() -> SessionGroup

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.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

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

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

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

§

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

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more