pub(crate) struct Reporter<'a> {
observer: &'a dyn ProxyObserver,
enabled: bool,
counters: &'a Recorder,
session_id: SessionId,
side: ProxySide,
stream_id: Option<u64>,
}Expand description
Where this module’s events and counters go.
Holds the session identity so no call site has to restate it, and holds
the Recorder so that a counter bump and its event are one function
call apart at most. Borrowed rather than owned: it is built per call from
session.rs’s ForwardCtx, which this module deliberately does not
name.
Fields§
§observer: &'a dyn ProxyObserver§enabled: boolCached observer.wants_events(). Gates events only — counters
are unconditional.
counters: &'a Recorder§session_id: SessionId§side: ProxySide§stream_id: Option<u64>Implementations§
Source§impl<'a> Reporter<'a>
impl<'a> Reporter<'a>
Sourcepub(crate) fn new(
observer: &'a dyn ProxyObserver,
enabled: bool,
counters: &'a Recorder,
session_id: SessionId,
side: ProxySide,
stream_id: Option<u64>,
) -> Self
pub(crate) fn new( observer: &'a dyn ProxyObserver, enabled: bool, counters: &'a Recorder, session_id: SessionId, side: ProxySide, stream_id: Option<u64>, ) -> Self
Build one for a stream direction, or for the datagram path
(stream_id: None).
Sourcepub(crate) fn applied(&self, site: Site, action: ActionKind, effect: Effect)
pub(crate) fn applied(&self, site: Site, action: ActionKind, effect: Effect)
One ProxyEvent::ActionApplied, for one phase of one action — and
the counter, for the two kinds that have one.
The bumps sit outside the enabled gate, on exactly the terms
Self::refused gives for its own: a session with nobody watching
still counts what it did, and a counter that moved only when someone
was looking would agree with its event by construction rather than by
measurement.
Each kind reaches this method once per unit it was applied to,
which is what makes a match on the kind a count and not an
over-count. check_composition refuses Delay and Hold as an
inner action and refuses Truncate and ResetStream as a wrapped
one, so a composition can hold neither of these two; and
Self::applied_deferred, which reports the inner kind when a
deferred unit is released, can therefore never name either of them.
A delayed unit is counted at its decision and reported again at its
release under whatever it was wrapping, and only the first of those
two is a Delay.
Sourcepub(crate) fn applied_deferred(&self, site: Site, deferred: Deferred)
pub(crate) fn applied_deferred(&self, site: Site, deferred: Deferred)
The release-phase half of a Action::Delay / Action::Hold.
Always at Site::Object or Site::Control — the two sites with
a queue — and always with the inner action’s kind, which is what
tells it apart from the Queued event emitted at the decision.
Sourcepub(crate) fn refused(&self, site: Site, action: ActionKind, refusal: Refusal)
pub(crate) fn refused(&self, site: Site, action: ActionKind, refusal: Refusal)
One ProxyEvent::ActionRefused, and one actions_refused.
The counter is bumped outside the enabled gate on purpose: a
session with no observer attached still counts what it refused, and
the counter and the event are asserted independently. Bumping it
inside would make the two agree only when someone was watching.
Sourcepub(crate) fn failed(&self, site: Site, action: ActionKind, error: String)
pub(crate) fn failed(&self, site: Site, action: ActionKind, error: String)
One ProxyEvent::ActionFailed: the action was admitted and the
transport rejected it.
Called by session.rs, not from here — this module produces the
bytes and the plan, and the caller hands them to the transport, so
only the caller can see the rejection.
It follows an ActionApplied for the same attempt rather than
replacing one. execute emits the admission before it returns, and
the caller cannot un-emit it once the transport declines; the two
together say the engine did it, and it did not arrive, which is the
whole truth and neither event carries it alone. What this is exclusive
of is ActionRefused: a refused unit was never the engine’s to place,
so a transport failure on its bytes is
ImpairmentKind::DatagramNotSent instead.
Note the event carries no stream_id: it is the datagram path’s, and
a datagram has no stream to name.
Sourcepub(crate) fn impairment(&self, kind: ImpairmentKind)
pub(crate) fn impairment(&self, kind: ImpairmentKind)
One ProxyEvent::Impairment, carrying the connection it is about.
The leg is worked out here, from the kind, rather than being a parameter each call site supplies. A site knows one thing — the direction it reads from — and most of what this enum reports is a failure to write, which belongs to the other connection. Asking twenty sites to make that turn is asking for the one to get it wrong that nothing downstream can catch: the event still arrives, still carries a leg, and names the wrong one.
See crate::event::impairment_leg for the table and for why four
kinds answer None.
§Ordering
Every caller of this is past the thing it is reporting: the reset has
been handed to the transport, the datagram has come back refused, the
queue has been abandoned. That is a rule about the call sites rather
than something this function can enforce, and it is stated on
ProxyEvent::Impairment because it is what an observer is entitled
to rely on.