Original text:
AbsoluteRange (0x4): Specifies a closed subscription starting at StartObject in StartGroup and ending at EndObject in EndGroup.  The <del> start and end of the range are inclusive. </del>  A filter type other than the above MUST be treated as error.

Reviewer comments:
The other option is we can use a delta encoding to make it impossible to specify an earlier object, but I think that would make it more complex.
Good point, I changed it to the same or later object
As mentioned in the sprawling , I think we should allow empty subscriptions, aka subscriptions that match no objects. It would be nice to have a way to check if a track exists without receiving any OBJECTs. The MoQ equivalent of a HTTP HEAD request. It could be useful to pre-warm the cache. An empty subscription could be the equivalent of "I'm interested, but don't have the bandwidth to receive objects yet". Again, similar to HTTP HEAD requests. For example, a client could issue a to accomplish two separate things: The track exists if it gets a SUBSCRIBE_OK. The encoder/CDN starts producing the track. The client could resubscribe at any point to immediately start receiving the track.
Can the same be accomplished with: or any other range request where start==end? Is it ok for the publisher sends SUBSCRIBEOK and SUBSCRIBEFIN, or does your use case require the publisher to hold the subscription open? Adding a new message is also an option.
I think there's a few potential use-cases: Check if the track exists. Check if the track is active. Check if the track is active, and get notified when the track is closed. Check if the track exists and group/object N exists. "exists" vs "active" is tricky. If you request absolute/0, then it's totally valid for the relay to return OK so long as the objects haven't expired yet, even if the publisher sent a FIN a long time ago. But what should the relay do if absolute/0 has expired? Should it return an error, even if the track is still actively producing objects? Requesting relative/0 is better, although what if that object has expired too? For example, a muted audio track. IMO ? SUBSCRIBE start/end=none ... UNSUBSCRIBE SUBSCRIBE start/end=none ... SUBSCRIBEFIN SUBSCRIBE start/end=absolute/N ... SUBSCRIBEFIN
And a more concrete use-case that NAME and NAME might like. Let's say I have 3 renditions: . The client starts watching a broadcast: This is a hint to the relay that the 720p track exists and it should start warming the cache. The relay is free to ignore the hint, but at the very least it will perform authentication. When the client decides that it has enough bandwidth for 720p, it will switch up at an aligned group: If the relay warmed the cache, then this switch is instantaneous. If the relay ignored the hint, then it takes at least an RTT to origin to fetch the 720p track. The time it takes to switch renditions matters more when switching down in response to congestion. The buffer will deplete while the CDN fetches the rendition from origin, which pre-warming subscriptions will avoid. And just to complete the example, you have to pre-warm the 480p SUBSCRIBE again. This could either be done with multiple subscriptions, or waiting until the SUBSCRIBE_FIN arrives and then subscribing again. I'm not quite sure which approach is better.
I'm a little concerned about this use case, for the reasons below: Is the assumption that the catalog, which declares the existence of the track, is not trustable? How? If the relay went forward to the origin with the same start=none request then the origin should not actually send anything and therefore the cache would not fill. The only way this works is if the relay goes forward with a different request with some !none start value. This non-deterministic behavior (ask one component for one thing and it asks for somehting else) can lead to scaling and debugging problems. I appreciate the benefits of cache warming, for fast start especially when the the edge relay is far from the origin. There are other ways to achieve this. One way can be by having a "warming client" make a conventional subscription request. This client may be an agent hosted on the edge relay for this purpose and its APi would be offered by the CDN and is outside the scope of moqt. As a third point, empty subscriptions are also a DDOS attack vector. As a client, if can make a hundred requests for streams that all then flow to a relay, but no content actually comes to me, it is a highly asymmetric (and therefore dangerous) DDOS tool.
I think it's useful for applications that don't use a catalog. ex. Alan's chat protocol could check if a chat room or participant exists by performing an empty subscribe. The relay doesn't have to forward ranges verbatim. Just like if a CDN receives a HEAD request, the relay MAY issue a GET request to the origin instead. I think this is actually pretty common? In the MoQ case, the relay could request instead of from the origin. It's completely up to the relay; it would only do this if there's sufficient bandwidth/cache available. It's a little bit of business logic though; maybe the customer can choose to enable it. Just keep in mind that we don't want the relay to have access to the catalog. So you're asking applications to provide this functionality, requiring a custom service worker, a custom player, and hooks to notify the service worker on player start/stop. And the service worker itself doesn't actually want to receive these objects, so yeah there would need to be a non-standard API to actually warm a track. Plus it gets more complicated when you through in alternative renditions. Maybe the client has no intention of downloading AV1 tracks, or maybe it has no intention of downloading Japanese subtitles. This sort of selection criteria should be signaled to the service worker; pre-warming all tracks is a waste. I think this is the type of thing we build into the protocol instead of asking every application make a unique implementation. Warming would be completely optional for both the publisher and subscriber. I don't quite understand. The CDN would deduplicate subscriptions so only one would ever reach the origin for a given track. If the relay already has an active subscription for the 480p track, then it wouldn't need to issue another subscribe upstream to serve empty subscriptions. But if you're talking about using random track names, a client can already SUBSCRIBE to random track names (just like random HTTP paths) to DoS the origin. Or maybe you're talking about a client potentially pre-warming a bunch of valid tracks. Like somebody wrote a bot to scrape all Twitch broadcasts with zero viewers and issued an empty subscribe to them all. The CDN is completely in charge of determining if it pre-warms empty subscribes, which it should not do if it's near capacity or detects abuse. But I don't think this is unique to empty subscribes. A client could perform a normal subscribe and then either immediately unsubscribe, close the connection, or set MAXSTREAMSUNI=0 avoid receiving any objects. These empty subscribes follow the normal authentication logic, so the mitigation is going to be the same for both.
Individual Comment: Let's retitle this issue to be more specific about what the ask is. Empty subscriptions are possible with draft-01. Their semantics are a bit undefined - eg: a relay or publisher has multiple options - SUBSCRIBEERROR, SUBSCRIBEOK + SUBSCRIBEFIN, SUBSCRIBEOK and no FIN, in case the subscriber wants to do something else? Do we need to mandate a particular behavior for better interoperability? Then there's a separate issue about supporting these use cases: If these are required, then there's other ways to spell that without changing Subscribe - and none of these cases have anything to do with subscribing except maybe 3? A QUERY_TRACK (eg: HEAD) message that doesn't alter the subscribe state seems like a more apt vehicle. How to pre-warm a cache seems out of scope. I think we should open a separate issue about this case, and what the relay requirements are (if any) around backpressure. The same thing can happen if a client runs out of streams and doesn't grant new credit in a timely way. Are there obligations to keep the subscription open and/or cache at the relay for some period of time, or can a relay aggressively drop objects or reset subscriptions? A naive relay is going to get itself in big trouble very quickly.
Now that we have TRACKSTATUSREQUEST, can we close this one? The one use case we haven't completely addressed explicitly is cache pre-warming, which is tracked by
LGTMAfter or equals to? (in case one requests a single object)

Revised text:
AbsoluteRange (0x4): Specifies a closed subscription starting at StartObject in StartGroup and ending at EndObject in EndGroup.  The  <ins> start and end of the range are inclusive.  EndGroup and EndObject MUST specify the same or a later object than StartGroup and StartObject. </ins> A filter type other than the above MUST be treated as error.