-
Notifications
You must be signed in to change notification settings - Fork 50
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
Relative prioritization of streams and datagrams #610
Comments
There is a sendOrder and sendGroup scheme in the WebTransport API which would meet the MoQ requirements, but it only applies to Streams. One way to satisfy the MoQ requirement would be to also put flows of Datagrams into sendGroups of their own and then allow the application to assign the relative priority of those against other stream-based sendGroups. This has been discussed in #451 and #515 but after much discussion was never adopted. |
I do wonder if we should just give datagrams a sendGroup/sendOrder, that would probably be better than the current wording. Maybe we could even have multiple datagram queues with different priorities. |
What's the use case? I understand putting audio in datagrams and video in stream-of-streams, and giving audio priority.
I suspect it's incompatible even before #604 when things were implementation-defined, but agree we may have to rethink. Chrome sends all datagrams > all streams whereas Firefox sends all streams > all datagrams. Neither seems moq compatible. What are moq's requirements?
I think we're talking about weights here (between groups), not send ordering (within groups).
Sounds like #419. I'd like to first explore what the incompatibility is. At least for deterministic priorities, we've assumed the app can control the total datagram to stream ratio by how many total datagrams it queues per second. User agents could in theory base their send-buffer dequeuing strategy on its assessment of how quickly datagram send-queues build up, compared with other send-queues. This was a benefit perhaps of keeping things vague. But how would we capture this in a spec? It would be unfortunate if we grew JS APIs for lack of ability to do so. |
The simplest use-case is that moq control messages go on a stream, which should have higher priority than any media (streams or datagrams). We have also considered having N control streams (and still might).
moq needs WebTransport to expose a way to set the priority of a datagram in the same priority space as streams (eg: think of it as a 1 packet stream). If that proves too costly, some other way of assigning a flow of datagrams a priority within the same space.
moqt doesn't define any weighting (eg bandwidth sharing) schemes at present. There's an algorithm to determine the highest priority "object" to send next, and only that will be sent until it is complete or becomes app limited. |
Meeting:
|
@wilaw and I were discussing an example to see if this would work (feel free to post your own): Example 1. I'm sending:
What should happen under congestion? Today this won't work: D will be sent ahead of everything else (then A, B and C get ⅓ of what's left) API option 1: wt.datagrams.sendGroup = S; wt.datagrams.sendOrder = n
Here, C would starve D would starve A and B if needed. |
The above puts different flows in the same sendGroup, breaking any notion that one was supposed to create a sendGroup per flow. Maybe that's fine since one clearly can, but it might come back to bite us. E.g. two sendOrder-using stream-of-streams flows in the same sendGroup would yet again be forced to lockstep their increment/decrement strategies (why we introduced sendGroups in the first place). If the main objection to #419 was "weights" being relative, we can replace it with strict priority: API option 2: wt.datagrams.strictPriority = 1; S.strictPriority = 2
Here datagrams acts as its own inherent send group (we can still consider constructing multiple). |
API option 1 doesn't work because datagrams don't fit in send groups API option 2 seems cleaner to me: const a = await wt.createUnidirectionalStream();
const b = await wt.createUnidirectionalStream();
const s = wt.createSendGroup();
s.strictPriority = 2; // new
const c = await wt.createBidirectionalStream({sendGroup: s});
const d = wt.createDatagramsWritable(); // new
d.strictPriority = 1; // new
await readableDatagrams.pipeTo(d); Less rope for web developers. |
Meeting:
|
The idea was to treat datagram writeables as streams for the purposes of prioritization. There would need to be differences in other aspects, like stats. My suggestion would be to expand the getStats to include datagram stats separate from stream stats. |
I was recently looking at modifying the mvfst QUIC API to add datagram prioritization and came to a similar idea. |
|
Meeting:
|
Meeting (adding notes late from this morning):
|
This appears directly supported in proposal 2 as shown in the slides. If someone from MOQ could elaborate on the use case for this that would be great. In lieu of a better example, here's random one: for (let i = 0; i < 256; i++) {
const flow = (i % 2) ? wt.datagrams.createWritable() : wt.createSendGroup()
} Without priority, the first-queued datagrams queued on each writable competes with the stream with the highest sendOrder in each group. Strict priority addresses this head on (higher numbers take precedence): for (let i = 0; i < 256; i++) {
const flow = (i % 2) ? wt.datagrams.createWritable() : wt.createSendGroup()
flow.priority = i;
} But strict priorities seem indistinguishable from (and can be accomplished using) really large weights: for (let i = 0; i < 256; i++) {
const flow = (i % 2) ? wt.datagrams.createWritable() : wt.createSendGroup()
flow.weight = i * 1_000_000;
} What use case is not covered here? |
As someone who is not present at the meeting where proposal 2 was presented, it is difficult to distill the proposal from the slides. Can you provide a brief summary of the proposed priority algorithm, including the input signals (send groups, send order, priorities, weights) and how the algorithm picks the next thing based on the signals of elements that are in the queue? I'm not sure "MoQ desires 256 strict priority levels" is an accurate description of the current moqt draft. The subscriber and the publisher can each set an 8 bit priority field for data in a track, which are combinable into a 16 bit field (subscriber > publisher). There's further ordering that happens when multiple elements (streams or datagrams) belong to the same track. |
Note that the proposed solution doesn't actually work. If the premise here is that we can simulate absolute priority between two streams by making their weights 1000000:1, the proposed formula ( |
We created some slides to help further discussion on this issue: https://docs.google.com/presentation/d/1ciJ3tdN0lOJbWkNg9jwgsjf3ye3Q9fTHQBucBK26Hlg/edit?usp=sharing |
Meeting:
|
Media over QUIC recently merged a PR defining how moq will use priorities (moq-wg/moq-transport#470). The scheme is based on the MoQ object model (track, group, object) and is independent of how that object model is mapped to QUIC or WebTransport constructs (streams and datagrams). It is possible for a MoQ application to specify a track that maps to a stream be given higher priority than a track that maps to datagrams. Jan-Ivar presented at IETF 120 and mentioned that WebTransport now gives priority to datagrams over streams unilaterally, which is incompatible with moq's scheme.
The text was updated successfully, but these errors were encountered: