Original text:
Final Object: The largest Object ID sent by the publisher in an OBJECT message in the "Final Group" for this track. <del> 6.10. </del>  The publisher sends the ANNOUNCE control message to advertise where the receiver can route SUBSCRIBEs for tracks within the announced

Reviewer comments:
Into SUBSCRIBEDONE. I didn't remove the SUBSCRIBEERROR message in favor of SUBSCRIBE_CLOSED as NAME suggested in this PR. Addresses some comments in , but possibly not all
So my notes from this discussion. CLOSE is confusing with QUIC layer. People seemed to prefer UNSUBSCRIBE over SUBSCRIBE_CLOSE. I love the move aware from RST and FIN as naming.
Propose names from my understanding of discussion call Announce (send by publisher) , AnnouceOK, AnnouceError UnAnnounce (send by publisher) UnAnnounceOK, UnAnnounceError AnnouceEnd ( sent by thing that received Annouce) , AnnouceEndOK, AnnouceEndOK Subscribe (send by subscriber) , SubscribeOK, SubscribeError UnSubscribe (send by subscriber) , SubscribeOK, SubscribeError SubscribeEnd (send by thing that received subscriber), SubscribeOK, SubscribeError Mostly trying to get rid of FIN / RST and have different names for the messages that flow in opposite directions.
I don't like the name of the different messages used to terminate. I'd rather have one message that transitions to the terminal state, with an optional error code and final group/object. IMO the subscription flow: And the ANNOUNCE flow mirrors: The brackets mean a message is optional. The sender is responsible for creating and the receiver is responsible for closing, possibly at the bequest of the sender (like QUIC's STOP_SENDING).
has been merged, adding yet another term (CANCEL), but I figured we'd clean that up with this issue.
Since we are bikeshedding, I prefer ANNOUNCE_RESCIND instead of CANCEL, since an announce is more of a declarative statement than an active request from the sender.
Heh and UNANNOUNCE and UNSUBSCRIBE stick out because they don't share the same prefix.
I like the names being proposed as they help make make is easier to understand. I do want to separate out one issue. The STOP / CLOSE type thing happens way after the initial SUBSCRIBE thus it can end up in a situation where auth has expired or something else has gone wrong this I like the current design that allows an OK or ERROR to be returned for those. I think it is also key for sender of the things stoping the subscribe to know that the other side has acted on that so we need the OK.
I'm leaning towards CLOSED instead of CLOSE because CLOSE implies its a requested action, so to me SUBSCRIBE_CLOSE sounds like something the subscriber would send, not the publisher. For a similar reason, I like CANCEL slightly better than STOP, but both work. UNANNOUNCE and UNSUBSCRIBE are good words, but I think it's better to follow a pattern in this case and I like NAME sequence of messages.
NAME CANCEL and CLOSED are slightly better, sure. NAME there MUST still be an OK before objects can be sent. That way the receiver can tell upon receipt of the CLOSED if the subscription was ever active.
So to add an OK, we need to add another state. The question for me is what is the use case where we need to deliver that information in the end of the subscribe.
This discusion is probably easier looking at state machine diagrams
Sections 6.8 and 6.9 strongly imply that SUBSCRIBEFIN/RST are sent at the true end of the track. So are they not sent at the conclusion of a SUBSCRIBE that does not cover the end of the track? For example, if the last object of a track is (10, 12), and there's one subscribe for (4,0) to (5, 100) Is there a SUBSCRIBEFIN? If not, how does the subscriber know that in fact (5, 60) is the last object in that subscription? If so, does Final Group and Final Object refer to the last object in the subscription?
Individual Comment: Putting my HTTP hat on for a second, when you ask for something with unknown length, you infer from a graceful termination that the last thing you got was the true end of that resource. If you send a range request, the graceful termination at the end does not convey that the last thing was the true end. Once the object expires, you can issue another request to the same name and potentially get a totally different thing. Does this model work for moq, or do we need something different?
There are three different things you might want to communicate to a receiver at the end of the subscribe: 1) You got all of the objects in the range; 2) You got almost all of the objects, but some were dropped for latency/bandwidth reasons 3) The track was truncated for some reason and possibly, 4? 4) You got everything I have but i'm not sure if that's everything
is somewhat relevant to this issue.
As mentioned in , there are 3 different ways for a publisher to close a subscriber, each with minor differences. : I never sent you an object. : There are no more objects to send after group/object X/Y. : There are more objects after group/object X/Y... but I won't send them. A few things: I think it should be renamed since it's not the only ERROR message. Maybe ? The only difference is that one has an error code. Otherwise they both include a final group/object and it's up to the application/library to decide if they wait for the final object(s). I'd like to only implement this once but right now I have to copy/paste any code to handle these almost identical messages. What if we merged them and use error code 0 to signal a FIN. The reason phrase should be removed as part of . There really needs to be a state machine like with this many ways to terminate a subscription. I think these are all protocol violations: then then then My interpretation of the draft is that a followed by a is invalid, which is not obvious and unlike QUIC. I don't think so. The library/relay behavior doesn't change based on . The only thing that miiiight differentiate between the two is the application, which can use errors codes for this purpose. At the very least I would merge these two messages. But I would also like to explore a single way for the publisher to close a subscription. The application can signal the nuanced differences between errors (ex. error code 404 vs 410). The library/relay doesn't care, it just forwards the error code.
Individual Comment: The inspiration for FIN vs RST in moq came from HTTP caching. If a resource has no content-length, and the caching proxy has received N bytes, does it have the entire resource, or does it need to refetch the tail? If that response was terminated with a FIN (H2 or H3), then it has the whole resource. If it was terminated by a RST, it can't assume that it does. So the value I see in these two messages is for a moq relay is similar. A client connected to the relay and subscribed to a track, which fowarded the subscribe to a publisher. The track was published to the relay and ended with a FIN. Another client subscribes to this track from the beginning (Absolute/0,0) and no end. Does the relay need to resubscribe upstream? Now suppose that the connection from the publisher to the relay closed abruptly, or the track was terminated with SUBSCRIBE_RST. This is a signal to the relay that it's worth another subscribe to find out where the end of the track is. I can live if we consolidate the framing to a single message, and define a special error code to mean FIN, but I do think the transport needs to see the difference.
I like it. I would also like to merge ERROR with CLOSED, but we'll chat about that.

Revised text:
Final Object: The largest Object ID sent by the publisher in an OBJECT message in the "Final Group" for this track.  <ins> 6.9. </ins> The publisher sends the ANNOUNCE control message to advertise where the receiver can route SUBSCRIBEs for tracks within the announced