Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Figure out how to expose rolling average stats like RTT #374

Closed
jan-ivar opened this issue Oct 27, 2021 · 9 comments · Fixed by #386
Closed

Figure out how to expose rolling average stats like RTT #374

jan-ivar opened this issue Oct 27, 2021 · 9 comments · Fixed by #386
Assignees

Comments

@jan-ivar
Copy link
Member

jan-ivar commented Oct 27, 2021

At TPAC I proposed we follow WebRTC's precedent for exposing stats that are of interest over a rolling window. Discuss.

WebRTC has the following:

dictionary RTCRemoteInboundRtpStreamStats : RTCReceivedRtpStreamStats {
             DOMString            localId;
             double               roundTripTime;
             double               totalRoundTripTime;
             double               fractionLost;
             unsigned long long   reportsReceived;
             unsigned long long   roundTripTimeMeasurements;
};

While it has a roundTripTime time which is the most recently reported value from RTCP, of interest to me is the other two, which are totalRoundTripTime and roundTripTimeMeasurements.

I propose we add those two to WebTransport stats. cc @martinthomson who I believe had some comments.

@jan-ivar jan-ivar changed the title Avoid hardcoded rolling average on RTT Avoid hardcoded rolling average on stats like RTT Oct 27, 2021
@martinthomson
Copy link
Member

So RTT estimation using the EWMA method that most stacks use is a little constraining. However, I don't think that providing less information and expecting that to be better is the right outcome. If (it's a big if) we want to provide sites with a better way of estimating RTT, then we should provide them with a stream of timestamped samples.

@jan-ivar
Copy link
Member Author

jan-ivar commented Nov 1, 2021

I've provided WebRTC as a precedent, but if there are other precedents or expectations we should follow, please add links. It may be that we should follow those.

The first question I suppose is if minRtt, the "minimum RTT observed on the entire connection", is sufficient. To me it seems like an extremely optimistic figure, likely a near constant. It's not likely to change appreciably, and if it does, only in one direction, which seems to fail as any ongoing monitor of network condition.

I'm not seeing how it's less information, since JS can construct all other info from it. Less processed perhaps?

const base = await wt.getStats();
await new Promise(r => setTimeout(r, 1000)); // app-controlled window
const stats = await wt.getStats();

console.log((stats.totalRoundTripTime - base.totalRoundTripTime) /
            (stats.roundTripTimeMeasurements - base.roundTripTimeMeasurements)); // last second average rtt

This pushes the calculation on JS, and doesn't require keeping a series of (how many?) samples. It was WebRTC's attempt to be measurement agnostic. if we don't like that, we don't have to follow it. But some consistency would be nice.

@martinthomson
Copy link
Member

minimum RTT is generally measured over a period (otherwise we won't allow for path changes that result in the true value increasing); QUIC has specific language about that

maybe this isn't less information inasmuch as it is differently processed.

note that anything you provide here will always be in addition to what the browser is doing. the browser needs to maintain its own estimates

@wilaw wilaw added the Discuss at next meeting Flags an issue to be discussed at the next WG working label Nov 3, 2021
@aboba
Copy link
Collaborator

aboba commented Nov 8, 2021

@jan-ivar The following paper has a list of metrics used to build an RTP over QUIC implementation. This includes RTT variance as well as detailed one-way packet timing information (based on a QUIC extension).

@martinthomson
Copy link
Member

Here's what we can produce easily:

pub struct Stats {
    info: String,

    /// Total packets received, including all the bad ones.
    pub packets_rx: usize,
    /// Duplicate packets received.
    pub dups_rx: usize,
    /// Dropped packets or dropped garbage.
    pub dropped_rx: usize,
    /// The number of packet that were saved for later processing.
    pub saved_datagrams: usize,

    /// Total packets sent.
    pub packets_tx: usize,
    /// Total number of packets that are declared lost.
    pub lost: usize,
    /// Late acknowledgments, for packets that were declared lost already.
    pub late_ack: usize,
    /// Acknowledgments for packets that contained data that was marked
    /// for retransmission when the PTO timer popped.
    pub pto_ack: usize,

    /// Whether the connection was resumed successfully.
    pub resumed: bool,

    /// The current, estimated round-trip time on the primary path.
    pub rtt: Duration,
    /// The current, estimated round-trip time variation on the primary path.
    pub rttvar: Duration,

    /// Count PTOs. Single PTOs, 2 PTOs in a row, 3 PTOs in row, etc. are counted
    /// separately.
    pub pto_counts: [usize; MAX_PTO_COUNTS],

    /// Count frames received.
    pub frame_rx: FrameStats,
    /// Count frames sent.
    pub frame_tx: FrameStats,

    /// The number of incoming datagrams dropped due to reaching the limit
    /// of the incoming queue.
    pub incoming_datagram_dropped: usize,

    pub datagram_tx: DatagramStats,
}

pub struct DatagramStats {
    /// The number of datagrams declared lost.
    pub lost: usize,
    /// The number of datagrams dropped due to being too large.
    pub dropped_too_big: usize,
    /// The number of datagrams dropped due to reaching the limit of the
    /// outgoing queue.
    pub dropped_queue_full: usize,
}

@wilaw wilaw added this to the Candidate Recommendation milestone Jan 5, 2022
@jan-ivar jan-ivar changed the title Avoid hardcoded rolling average on stats like RTT Figure out how to expose rolling average stats like RTT Jan 5, 2022
@wilaw
Copy link
Contributor

wilaw commented Jan 12, 2022

Firefox smoothing calc seems like an EWMA of 8 samples
https://searchfox.org/mozilla-central/rev/83e67336083df9f9a3d1e0c33f2ba19703d57161/third_party/rust/neqo-transport/src/rtt.rs#108
Do we need to standardize the window?

@jan-ivar
Copy link
Member Author

So based on that, how about this proposal, based on RFC6298:

partial dictionary WebTransportStats {
  DOMHighResTimeStamp smoothedRtt;
  DOMHighResTimeStamp rttVariation;
};

@martinthomson
Copy link
Member

@wilaw, That is standardized in RFC 9002: https://quicwg.org/base-drafts/rfc9002.html#name-estimating-smoothed_rtt-and

You could cite that rather than RFC 6298 though QUIC's algorithm derives from RFC 6298, a more specific reference is good.

@jan-ivar, those names are good.

@jan-ivar jan-ivar self-assigned this Jan 18, 2022
@jan-ivar
Copy link
Member Author

Meeting:

  • Looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants