Skip to main content

SessionShaper

Struct SessionShaper 

Source
struct SessionShaper {
    plane: Option<Arc<ControlPlane>>,
    classes: Vec<String>,
    current: Mutex<CachedShaper>,
}
Expand description

One session’s shaper, and the proxy profile it watches.

A session builds a Scheduler from the profile it was configured with and shares it through the whole forwarding scope. That much has not changed. What this adds is a place to notice that the proxy has been given a different profile while the session runs, and a rule about when the session is allowed to act on it.

§The swap happens between streams, never inside one

Self::current is read once per forwarded stream, and the Arc<Scheduler> it hands back is what that stream classifies with, queues under and paces against for the whole of its life. A stream that is already forwarding keeps the scheduler it started with even after the profile has moved on.

That is forced rather than chosen. A Class is an index into a scheduler’s class list, and a stream’s egress queue holds the scheduler its units were admitted under. Swapping mid-stream would classify a unit against one profile’s rules and release it against another profile’s buckets and demand rows — charging a class that is not the one that was matched, or, where the new list is shorter, a class that does not exist. Reading it per stream costs one Mutex acquisition where a PendingQueue is already being built.

§A profile with a different class list is not taken up at all

The session’s ShapeRecorder has one row per configured class, pre-sized when the session is constructed and never resized, and a class is charged to its row by position. A profile whose class list differs from the one those rows were named after would therefore keep every number correct and make every label on it wrong. So a live profile is taken up only when its class names match, in order, the ones this session started with; otherwise the session keeps its own until it ends. Changing the class list of a running session is done by ending it.

Fields§

§plane: Option<Arc<ControlPlane>>

The proxy this session belongs to, or None for a session driven directly rather than through an accept loop — which has no proxy, so no profile can be installed on it and this never looks.

§classes: Vec<String>

The class names this session’s statistics rows were pre-sized from, and the test a live profile has to pass to be taken up.

§current: Mutex<CachedShaper>

The scheduler in force, and the profile generation it was built at.

Implementations§

Source§

impl SessionShaper

Source

fn new(profile: ShapeProfile, plane: Option<Arc<ControlPlane>>) -> Self

Build the shaper for a session configured with profile.

profile is what the session’s statistics rows were pre-sized from, so its class list is the one every later swap is measured against. A profile installed on the proxy between the session’s configuration being copied and this call is taken up here, under the same rule a later one would be — that window is short, but a session that ignored it would run on a profile the proxy had already replaced with no way to notice.

Source

fn current(&self) -> Arc<Scheduler>

The scheduler the next stream should run under.

Takes up a profile installed since the last call when its class list matches; otherwise hands back what this session already had. Either way the generation is recorded, so a profile this session declined is not re-examined once per stream for the rest of the run — and a later profile that does match is still taken up, because the comparison is always against the class list the session started with.

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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

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

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