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

Add delivery timeouts #449

Closed
wants to merge 5 commits into from
Closed

Add delivery timeouts #449

wants to merge 5 commits into from

Conversation

vasilvv
Copy link
Collaborator

@vasilvv vasilvv commented May 20, 2024

The timeouts in this PR are defined to to ensure that the invariant properties implied by the object delivery preference are maintained, e.g. if stream-per-group is used, it is impossible to accidentally timeout an object in the middle of the group.

Fixes #440

The timeouts in this PR are defined to to ensure that the invariant
properties implied by the object delivery preference are maintained,
e.g. if stream-per-group is used, it is impossible to accidentally
timeout an object in the middle of the group.

Fixes moq-wg#440
a relay should attempt forwarding objects, or zero to indicate that no such
time limit is provided. The specific semantics of this field depend on the
forwarding preference ({{object-message-formats}}) used by the objects on the
track in question:
Copy link
Collaborator

Choose a reason for hiding this comment

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

clarification question:
Since the Delivery Timeout is in the SubscribeOK, how does the relay expected to know it's value ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Assuming the objects the relay has to serve were delivered to it via moq subscriptions, it can cache and use the value it received when it performed the upstream subscription. This will work if the value is immutable per track.

There's a corner case here, where the relay receives an object from upstream before the upstream Subscribe OK. There's no way to know if the object has passed its delivery timeout. It's probably ok to assume the object is valid to deliver in this case.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@afrind thanks ..

I am trying to wrap my head around the right set of requirements :

  • what is a object property VS
  • what is per subscription property

DeliveryTimeout seems to be object property as defined by the publisher. It doesn't change per subscription ? OR do we expect these to change per subscription ? If not, CacheDuration PR seems to be heading the right direction

Copy link
Collaborator

@afrind afrind left a comment

Choose a reason for hiding this comment

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

Individual Comment

a relay should attempt forwarding objects, or zero to indicate that no such
time limit is provided. The specific semantics of this field depend on the
forwarding preference ({{object-message-formats}}) used by the objects on the
track in question:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Assuming the objects the relay has to serve were delivered to it via moq subscriptions, it can cache and use the value it received when it performed the upstream subscription. This will work if the value is immutable per track.

There's a corner case here, where the relay receives an object from upstream before the upstream Subscribe OK. There's no way to know if the object has passed its delivery timeout. It's probably ok to assume the object is valid to deliver in this case.

@suhasHere
Copy link
Collaborator

if stream-per-group is used, it is impossible to accidentally timeout an object in the middle of the group.

I am not sure what would be issue .. isn't its application's choice rather than transport requirement ? Just trying to understand the constraint better

@afrind
Copy link
Collaborator

afrind commented May 21, 2024

Individual Comment:

what is a object property VS what is per subscription property

I agree this should be more clear in this PR. I'm assuming this is an immutable track property reported in Subscribe OK. @vasilvv can you clarify?

if stream-per-group is used, it is impossible to accidentally timeout an object in the middle of the group.

I am not sure what would be issue .. isn't its application's choice rather than transport requirement ? Just trying to understand the constraint better

I think this highlights something that may require additional discussion; I get the sense different wg members have different assumptions about how streams move through relays.

My view is that when a publisher chooses to deliver objects in stream-per-group or stream-per-track modes, it is doing so because it wants the reliability and ordering guarantees QUIC provides to streams. Therefore, a relay can't remove an object from the middle of such a stream, since this changes the reliability properties my app depends on. The current draft has language reflecting this:

A relay MUST not reorder or drop objects received on a multi-object stream when forwarding to subscribers, unless it has application specific information.

With this in mind, I'm inclined to agree with the stream-per-group restrictions in this PR - if a relay is delivering a group on a stream, and encounters an object that has exceeded the delivery timeout and won't deliver it, the only option is to close the stream and move on. I'm also in favor of some kind of restriction on dropping objects using stream-per-track (either disallowing it entirely, or closing the stream).

If reordering or dropping objects at relays is important to application behavior, I would think the publisher would choose datagram or stream-per-object forwarding preferences.

Is there a use case for using stream-per-group/track, but allowing the relay to drop or reorder objects?

If so, how is it better than using a stream-per-object or datagram mapping?

Copy link
Contributor

@fluffy fluffy left a comment

Choose a reason for hiding this comment

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

I don't think this will work for a bunch of the use cases for a few reason:

  1. some use cases the times outs are not the same for all objects in the subscriptions

I need to think about if that is important or not

@suhasHere
Copy link
Collaborator

Therefore, a relay can't remove an object from the middle of such a stream, since this changes the reliability properties my app depends on.

This is not entirely true. If the application wants no objects to be dropped end to end across relats, it will set the duration to reflect its slowest subscriber ( in the case where there is a mix of different subscriber types ???) . This is done regardless of delivery mechanisms (stream mapping) being used .

@VMatrix1900
Copy link

Therefore, a relay can't remove an object from the middle of such a stream, since this changes the reliability properties my app depends on.

This is not entirely true. If the application wants no objects to be dropped end to end across relats, it will set the duration to reflect its slowest subscriber ( in the case where there is a mix of different subscriber types ???) . This is done regardless of delivery mechanisms (stream mapping) being used .

Delivery timeout only applies for real-time transmission, prioritizing data freshness over reliability. For DVR usecase(relays don't send this object more than 30 minutes after it was produced), 100% reliability is desired. This is more related to content policy: #448

@suhasHere
Copy link
Collaborator

Therefore, a relay can't remove an object from the middle of such a stream, since this changes the reliability properties my app depends on.

This is not entirely true. If the application wants no objects to be dropped end to end across relats, it will set the duration to reflect its slowest subscriber ( in the case where there is a mix of different subscriber types ???) . This is done regardless of delivery mechanisms (stream mapping) being used .

Delivery timeout only applies for real-time transmission, prioritizing data freshness over reliability. For DVR usecase(relays don't send this object more than 30 minutes after it was produced), 100% reliability is desired. This is more related to content policy: #448

From what i read, a delivery timeout of 0 means , no restrictions . yes , i do agree the some of the concerns is auth/policy related , as in, until when origin thinks the content is valid.

Copy link
Collaborator

@kixelated kixelated left a comment

Choose a reason for hiding this comment

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

I think this is the best approach by a mile. I'd also love the ability for the subscriber to indicate the delivery timeout too, so it could indicate the maximum jitter buffer size and let the publisher deal with dropping old content.

in question, and SHOULD reset all existing streams if those have been
already opened.
- If the Object Forwarding Preference is `Group`, once the specified number
of milliseconds has passed since the final object of the group was fully
Copy link
Collaborator

Choose a reason for hiding this comment

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

Interesting that this is based on the final object; I really like it.

@kixelated
Copy link
Collaborator

kixelated commented May 22, 2024

Is there a use case for using stream-per-group/track, but allowing the relay to drop or reorder objects?

@suhasHere

Absolutely not. Never attempt to reorder or introduce a gap in a QUIC stream. Use multiple streams at drop/reorder boundaries instead.

The application chooses these boundaries via the stream mapping. If you're using a stream per group, then you've forfeited the ability to drop/reorder individual objects which is entirely the point. Now the decoder doesn't need to deal with that possibility.

Copy link
Collaborator

@ianswett ianswett left a comment

Choose a reason for hiding this comment

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

Based on conversation Wednesday, @vasilvv is going to change this PR to be subscriber controlled.

ianswett added a commit that referenced this pull request May 27, 2024
Takes an opinionated approach to adding 'Fetch' style functionality within the existing mechanisms.

Can be improved once various TTL/etc PRs land.  For example, we can add a 3rd mode where In Order is preferred within a client specified Delivery Timeout. (#449).

Pulls in concepts from #428 

Fixes #269
Fixes #326
Fixes #350

Closes #421
ianswett added a commit that referenced this pull request May 27, 2024
@vasilvv
Copy link
Collaborator Author

vasilvv commented May 28, 2024

Based on conversation Wednesday, @vasilvv is going to change this PR to be subscriber controlled.

Did that (also since it's a parameter now, zero is no longer a special value).

Copy link
Collaborator

@afrind afrind left a comment

Choose a reason for hiding this comment

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

Individual Review

draft-ietf-moq-transport.md Outdated Show resolved Hide resolved
milliseconds has passed since the final object of the group was fully
received, the relay SHOULD NOT open new streams for the group in question,
and SHOULD reset all existing streams if those have been already opened.
- If the Object Forwarding Preference is `Track`, this parameter MUST NOT be
Copy link
Collaborator

Choose a reason for hiding this comment

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

In the current design, this means the forwarding preference of the track must be known by the subscriber. Perhaps it's better to a) ignore it or b) reset the stream after the timeout.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Should we necessarily design around the requirement of it being not known in advance, or a mismatch? I feel like if the subscriber expects something like stream-per-track, and it gets datagrams instead, it's going to have a bad time.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That's why I made Stream per track only used by the 'Strict In Order' mode in: #452

Copy link
Contributor

Choose a reason for hiding this comment

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

If we did this, I think track could be handled the same way of group and simply reset the stream and end the track if time has been exceeded.

Copy link
Contributor

Choose a reason for hiding this comment

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

Due to the DOS stuff discussed in Seattle, I think we should update this so that in all cases the time starts at when start receiving the first bytes

Copy link
Contributor

@fluffy fluffy left a comment

Choose a reason for hiding this comment

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

For this to make sense as a way to not get things that are outside the jitter buffer, I don't think this works to use the end of the steam. For the jitter buffer use case, it seems like we want this to work with datagrams and perhaps the other stream modes.

This would be better if it was limited to only be meaningful for final subscriber to relay. But if that relay is downstream of constrained link, then this does not solve the problem.

@@ -862,6 +862,32 @@ information in a SUBSCRIBE or ANNOUNCE message. This parameter is populated for
cases where the authorization is required at the track level. The value is an
ASCII string.

#### DELIVERY TIMEOUT Parameter {#delivery-timeout}
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like what this actually is a stream reset time

@suhasHere
Copy link
Collaborator

From the interim discussions:

  • it will help to elaborate a bit on the use-case (even informatively) and when the timeout is triggered esp for stream per group mapping and the expected behavior
    • Are we allowing for new group to trigger reset of the stream for the older group(s)
    • Does this span across multiple groups ?

@ianswett
Copy link
Collaborator

From an individual perspective, I think this functionality is interesting, though I realize there are more edge cases than I first thought.

For example, we're doing Object per stream, and there are 5 Objects in a group and they arrive in reverse order (for whatever reason), is the real intent that the last Object expires first? Similar question for any single Object that arrives late due to loss/etc. Differences on the order of an RTT or two will occur fairly regularly I expect, so it'd be good to clarify the expected behavior.

The other observation is that if one is willing to send frequent SUBSCRIBE_UPDATE messages that increase the Start, you can achieve very similar behavior without any direct reliance upon time and dealing with the question I just posed. Besides the annoyance of sending and processing SUBSCRIBE_UPDATE messages, is there a reason SUBSCRIBE_UPDATE can't solve the same problems?

Copy link
Contributor

@fluffy fluffy left a comment

Choose a reason for hiding this comment

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

Overall I think this changes what gets delivered next and would make more sense to discuss at Seattle interim.


- If the Object Forwarding Preference is `Datagram`, once the specified number
of milliseconds has passed since the datagram was received via this
subscription, the relay SHOULD NOT forward that datagram.
Copy link
Contributor

Choose a reason for hiding this comment

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

"received via this subscription" does not make sense to me.

milliseconds has passed since the final object of the group was fully
received, the relay SHOULD NOT open new streams for the group in question,
and SHOULD reset all existing streams if those have been already opened.
- If the Object Forwarding Preference is `Track`, this parameter MUST NOT be
Copy link
Contributor

Choose a reason for hiding this comment

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

If we did this, I think track could be handled the same way of group and simply reset the stream and end the track if time has been exceeded.

duration for which the relay should attempt forwarding objects. The specific
semantics of this field depend on the forwarding preference
({{object-message-formats}}) used by the objects on the track in question:

Copy link
Contributor

Choose a reason for hiding this comment

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

I think all these case could be exactly the same which is if the time is exceeded, the stream in use (if any) gets reset and for stream per track that implies no more of the track will be sent, for stream per group that imples no more of the group will be sent.


DELIVERY TIMEOUT parameter (key 0x03) MAY appear in a SUBSCRIBE or a
SUBSCRIBE_UDPATE message. It is a number of milliseconds indicating the
duration for which the relay should attempt forwarding objects. The specific
Copy link
Contributor

Choose a reason for hiding this comment

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

Give this does not somehow propagate to upstream relays, I don't think this will meet work for the use cases where the last relay is downstream of the congested link.

Copy link
Contributor

@fluffy fluffy left a comment

Choose a reason for hiding this comment

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

Need to sort out when time for expiry starts

ianswett added a commit that referenced this pull request Jul 12, 2024
Pulls in some text from #449 and attempts to convey the conclusions of the Seattle interim.

Closes #449
@ianswett
Copy link
Collaborator

Closing this in favor of #486

@ianswett ianswett closed this Jul 25, 2024
ianswett added a commit that referenced this pull request Jul 31, 2024
Pulls in some text from #449 and attempts to convey the conclusions of
the Seattle interim.

Adds Subscribe Parameters to SUBSCRIBE_OK to allow this parameter to be
optional in SUBSCRIBE_OK.

Closes #449
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Need expiry time / time to live
7 participants