Skip to content

WebTransport: stream priority #197

Open
@kixelated

Description

@kixelated

Hey folks,

I'm working on a proposed live media standard: Media over QUIC. I ported my library from quiche to quinn when I found the h3-webtransport crate. Big thanks to @darioalessandro and @ten3roberts for implementing it!

One thing that got lost in my migration was the ability to prioritize streams. It's critically important for MoQ and it's the key functionality that allows QUIC to deliver live media over congested networks. I specifically want send order, which means streams are transmitted in a strict order based on an integer priority (basically a priority queue).

Quinn implements send order but it is not implemented in the h3::quic trait or the h3_webtransport::SendStream struct. One of the problems is that there's no official QUIC API and nothing is sent over the wire, so stream prioritization is up to the implementation. Here's a few I've seen in the wild:

I think there's two routes to support stream prioritization.

1. Add set_priority to the h3::quic trait.

The debate would primarily be over the API. I'm a huge fan of a i32 (like Quinn) to match the JS API, but that would rule out other QUIC backends as they exist today.

I could work with a u8 like I did with quiche, but it's quite annoying. My application would maintain the stream priority queue and constantly update the stream priority with the index in the queue, limited to 256 streams outstanding at any time. Alternatively, I've discussed changing the quiche API with the authors and they're open to it.

I don't think an incremental flag is useful, even for the HTTP/3 Priorities. incremental=false is a solid default.

2. Add a mechanism to access the underlying SendStream.

The h3::quic trait makes a lot of sense for HTTP/3 since there's a set of core functionality required for HTTP/3. However, WebTransport models itself as QUIC on the web, which means exposing a nebulous "QUIC API". You can envision WebTransport as a thin layer on top of QUIC streams primarily for browser support.

I think it would be reasonable if the application could access the quinn::SendStream directly. For those unaware, WebTransport streams involve a few bytes at the start to identify the session_id. They behave like regular QUIC streams after that, although RESET_STREAM error codes use a special encoding to include the session_id.

I haven't explored if this would work, but maybe h3_webtransport::SendStream could implement inner(&mut self) &mut T or just DerefMut? It would be ideal if the application could not get access to the underlying quinn::SendStream.reset() to avoid misuse, which is why overloading it and using Deref might be better, but I think the h3::quic trait gets in the way.

Metadata

Metadata

Assignees

No one assigned

    Labels

    B-rfcBlocked: request for comments. Needs more discussion.C-featureCategory: feature. This is adding a new feature.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions