pub struct UnsentCounts {
pub invite: u64,
pub ack: u64,
pub bye: u64,
pub cancel: u64,
pub other: u64,
}Expand description
Requests the endpoint tried to put on the wire and could not, by method (§12.3).
Split by method because the consequence is. A CANCEL that does not go out leaves the far end ringing; an ACK that does not go out leaves a 2xx retransmitting for thirty-two seconds and then a peer streaming at a port this side has closed; a BYE that does not go out leaves a dialog up at the far end that no timer will reap. One number would hide which of those happened, and they are the three questions an operator asking “why did that call linger” is choosing between.
§Where this is counted, and why not at the hand-off
At the transmit, in the driver — the two places the socket is actually written: a
transaction’s Output::Send, and the direct send that carries an ACK for a 2xx.
It was counted inside crate::Handle::send and crate::Handle::send_directly when X-54
first wrote it, and that was wrong in a way the type’s own documentation concealed.
Handle::send returns as soon as the driver has created the transaction and handed back its
key; the transmit happens afterwards. So a counter at that hand-off could only ever fire when
the endpoint refused the request outright — a closed endpoint, or a request with no usable
Via — and never on a refused connection, an unreachable peer or an over-MTU datagram,
which is the whole of the question it claims to answer. send_directly did await the transmit,
so ack behaved one way and bye and cancel another, with nothing saying so. Counting where
the wire is missed makes all four mean the same thing.
§What this does and does not promise (§12.2)
- Requests only. A response that fails to transmit is counted by
DiscardCounts::send_failuresand not here, because these fields are methods and a response has none. - This overlaps
DiscardCounts::send_failureson purpose, and the two are views rather than tallies. A request that fails on the transaction path increments both: that field is the transaction path’s aggregate over requests and responses alike, this is the per-method breakdown over requests on any path. Adding them together is meaningless, and so is subtracting them — §12.2’s rule against arithmetic across fields applies here in particular. - An endpoint that is shutting down does not inflate this. A send that loses the race with
shutdownfails at the hand-off, before any transmit is attempted, and is not counted — the earlier design counted it, which made an ordinary teardown look like lost signalling.
Fields§
§invite: u64INVITEs the endpoint could not put on the wire.
ack: u64ACKs the endpoint could not put on the wire — RFC 3261 §13.2.2.4’s ACK for a 2xx, which has no transaction to retry it.
bye: u64BYEs the endpoint could not put on the wire. The one that leaves a call up at the far end.
cancel: u64CANCELs the endpoint could not put on the wire. The one that leaves a phone ringing.
other: u64Every other method the endpoint could not put on the wire.
Implementations§
Trait Implementations§
Source§impl Clone for UnsentCounts
impl Clone for UnsentCounts
Source§fn clone(&self) -> UnsentCounts
fn clone(&self) -> UnsentCounts
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for UnsentCounts
impl Debug for UnsentCounts
Source§impl Default for UnsentCounts
impl Default for UnsentCounts
Source§fn default() -> UnsentCounts
fn default() -> UnsentCounts
Source§impl PartialEq for UnsentCounts
impl PartialEq for UnsentCounts
Source§fn eq(&self, other: &UnsentCounts) -> bool
fn eq(&self, other: &UnsentCounts) -> bool
self and other values to be equal, and is used by ==.impl Copy for UnsentCounts
impl Eq for UnsentCounts
impl StructuralPartialEq for UnsentCounts
Auto Trait Implementations§
impl Freeze for UnsentCounts
impl RefUnwindSafe for UnsentCounts
impl Send for UnsentCounts
impl Sync for UnsentCounts
impl Unpin for UnsentCounts
impl UnsafeUnpin for UnsentCounts
impl UnwindSafe for UnsentCounts
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more