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

FIN, RESET_STREAM, RESET_STREAM_AT, STOP_SENDING #589

Merged
merged 24 commits into from
Oct 27, 2024
Merged
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 66 additions & 1 deletion draft-ietf-moq-transport.md
Original file line number Diff line number Diff line change
Expand Up @@ -2183,6 +2183,72 @@ The Object Status field is only sent if the Object Payload Length is zero.
A publisher MUST NOT send an Object on a stream if its Object ID is less than a
previously sent Object ID within a given group in that stream.

### Closing Subgroup Streams

Subscribers will often need to know if they have received all objects in a
Subgroup, particularly if they serve as a relay or cache. QUIC and Webtransport
streams provide signals that can be used for this purpose. Closing Subgroups
promptly frees system resources and often unlocks flow control credit to open
more streams.

If a sender has delivered all objects in a Subgroup to the QUIC stream, except
any objects that fall before the beginning of a subscription, it MUST close the
stream with a FIN.

If a sender closes the stream before delivering all such objects to the QUIC
stream, it MUST use a RESET_STREAM or RESET_STREAM_AT
{{!I-D.draft-ietf-quic-reliable-stream-reset}} frame. This includes an open
Subgroup exceeding its Delivery Timeout, early termination of subscription due to
an UNSUBSCRIBE message, a sender's decision to abandon the subscription before
the Subgroup is complete, or a SUBSCRIBE_UPDATE moving the end of the subscription
to before the current Group.

A sender might deliver all objects in a Subgroup to the QUIC stream, including a
FIN, and then reset the stream because any retransmissions are unnecessary due
to any of the reset conditions above being met. In this case, the receiving
application would receive the FIN if and only if all objects were, in fact,
delivered. The application can therefore ignore a RESET_STREAM if it receives
FIN.

If a sender does not deliver any objects from a Subgroup of a subscribed Group,
it MAY send a STREAM_HEADER_SUBGROUP on a new data stream, with no objects, and
then send RESET_STREAM_AT with a reliable_size equivalent to the length of the
stream header. This would explicitly tell the receiver that there are unsent
Subgroups in the Group.

Since SUBSCRIBEs always end on a group boundary [TODO: Update SUBSCRIBE to
express this], an ending subscription can always cleanly close all its
subgroups. A sender that terminates a stream early for any other reason (e.g.,
to handoff to a different sender MUST use RESET_STREAM or RESET_STREAM_AT.
Senders SHOULD terminate a stream on Group boundaries to avoid doing so.

An Original Publisher MAY create EndOfSubgroup objects to provide further
indication that streams are OK to close.

[TODO: Do we still need EndOfSubgroup objects?]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[TODO: Do we still need EndOfSubgroup objects?]
[TODO: Do we still need EndOfSubgroup objects?]

Good question, I don't think so? Fetch doesn't need them clearly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to get rid of these, but am happy to do it in a different PR to avoid controversy. If no one wants EndOf Subgroup, we can kill it now.

The edge case I can imagine is if FETCH contents can be SUBSCRIBEd (see #588). There's some ambiguity about FIN if the FETCH ends in the middle of the group. I would be happy to have that uncertainty, personally, but others might disagree.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to get rid of them too. Setting the object ID is problematic. If we need to, we can retain them for FETCH specifically (though the object ID problem is still there.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure there's a problem with FETCH? If you ask for the entire group, you get the entire group, if you ask for some Objects in a group, you get what you asked for with no indication as to whether it was the last object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not that there's a "problem" with Fetch; it's that if there are EndOfSubgroup objects, you are potentially sending a LOT of them in response to a FETCH.

Not in this PR, but I think we should get rid of EndOfSubgroup entirely. FETCH response should omit DNE and EndOfGroup status, because they are implied by sequence number gaps and the beginning of the next group, respectively.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote #596 to remove End Of Subgroup


An MoQT implementation that processes a stream FIN is assured it has received
all objects in a subgroup from the start of the subscription. If a relay, it
can forward stream FINs to its own subscribers once those objects have been
sent. A relay MAY use EndOfGroup, EndOfSubgroup, GroupDoesNotExist, and
EndOfTrack objects to close streams even if the FIN has not arrived, as further
objects on the stream would be a protocol violation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence is a bit confusing and I'm not sure it's what we want. Why would you send any of these messages and not FIN the stream?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes the FIN arrives in a separate QUIC packet. This sentence allows you to anticipate the later FIN.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still confused why a sender would do this, but I agree it's probably ok to do this.


Processing a RESET_STREAM or RESET_STREAM_AT means that there might be other
objects in the Subgroup beyond the last one received. A relay might immediately
reset the corresponding downstream stream, or it might attempt to recover the
missing Objects in an effort to send FIN, presumably with some timeout. It also
might send RESET_STREAM_AT with reliable_size set to the last object it has, so
as to reliably deliver the objects it has while signaling that other objects
exist.

A relay MAY also use EndOfGroup messages in a Subgroup stream to close streams
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just remove this, as it is implied, but seems complex.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't die on this hill, but why not explicitly give people permission to do this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair, maybe a reword would make me feel a bit better about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I slightly reworded and moved this paragraph, but I don't know if that solved your problem.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did make a suggestion on a way to rewrite the paragraph

for other Subgroups in that Group, if it has received all Object IDs between the
highest Object ID in the subject Subgroup and the EndOfGroup object. This may be
complex to implement.

A receiver MAY send a QUIC STOP_SENDING frame for a subgroup stream if the Group
or subgroup is no longer of interest to it.

### Fetch Header {#fetch-header}

Expand Down Expand Up @@ -2214,7 +2280,6 @@ Each object sent on a fetch stream after the FETCH_HEADER has the following form

The Object Status field is only sent if the Object Payload Length is zero.


## Examples

Sending a track on one stream:
Expand Down
Loading