diff --git a/draft-ietf-moq-transport.md b/draft-ietf-moq-transport.md index c2c09b88..359573e2 100644 --- a/draft-ietf-moq-transport.md +++ b/draft-ietf-moq-transport.md @@ -2175,6 +2175,71 @@ 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 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 publisher's decision to end the subscription early, or a +SUBSCRIBE_UPDATE moving the end of the subscription to before the current Group +or the start after the current Group. + +A sender might send all objects in a Subgroup and the FIN on a QUIC stream, +and then reset the stream. In this case, the receiving application would receive +the FIN if and only if all objects were received. If the application receives +all data on the stream and the FIN, it can ignore any RESET_STREAM it receives. + +If a sender will not deliver any objects from a Subgroup, it MAY send +a STREAM_HEADER_SUBGROUP on a new stream, with no objects, and +then send RESET_STREAM_AT with a reliable_size equal to the length of the +stream header. This explicitly tells the receiver there is an unsent Subgroup. + +Since SUBSCRIBEs always end on a group boundary, 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 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 treat receipt of EndOfGroup, EndOfSubgroup, GroupDoesNotExist, or +EndOfTrack objects as a signal to close corresponding streams even if the FIN +has not arrived, as further objects on the stream would be a protocol violation. + +Similarly, an EndOfGroup message indicates the maximum Object ID in the +Group, so if all Objects in the Group have been received, a FIN can be sent on +any stream where the entire subgroup has been sent. This might be complex to +implement. + +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 send all the objects in the subgroups and the FIN. 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 +might exist. + +A subscriber MAY send a QUIC STOP_SENDING frame for a subgroup stream if the Group +or Subgroup is no longer of interest to it. The publisher SHOULD respond with +RESET_STREAM or RESET_STREAM_AT. If RESET_STREAM_AT is sent, note that the receiver +has indicated no interest in the objects, so setting a reliable_size beyond the +stream header is of questionable utility. + +RESET_STREAM and STOP_SENDING on SUBSCRIBE data streams have no impact on other +Subgroups in the Group or the subscription, although applications might cancel all +Subgroups in a Group at once. ### Fetch Header {#fetch-header} @@ -2206,7 +2271,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: