Subject: Re: [quicwg/base-drafts] Independent states and REQUEST_RST (#171)

From: Mike Bishop <[email-masked]>
Date: Tue, 07 Mar 2017 09:58:45 -0800

@MikeBishop pushed 1 commit.

c9d0d8f  Servers shouldn't freak out either

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/171/files/dd17d054e308fb2940bc7027c1e613f87657dfe0..c9d0d8fe5c53e0f7672ab67f8ba47e8ef3e8eb7a

---

From: Mike Bishop <[email-masked]>
Date: Tue, 07 Mar 2017 10:14:17 -0800

@MikeBishop pushed 2 commits.

7f0a134  Rename to DISINTEREST
001c274  Suggest error code, loosen ordering

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/171/files/c9d0d8fe5c53e0f7672ab67f8ba47e8ef3e8eb7a..001c274f95c10fa225a75761f38f8d59bd24b7db

---

From: Mike Bishop <[email-masked]>
Date: Tue, 07 Mar 2017 10:21:38 -0800

d4f77df  an => a

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/171/files/001c274f95c10fa225a75761f38f8d59bd24b7db..d4f77df3f9c2c78726b9599bd6b34b65adc9cdeb

---

From: Mike Bishop <[email-masked]>
Date: Wed, 08 Mar 2017 16:08:58 -0800

dccd3f3  Merge remote-tracking branch 'origin/master' into request_rst

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/171/files/d4f77df3f9c2c78726b9599bd6b34b65adc9cdeb..dccd3f35ee751937b06f0ea48c8f1e342e79bab6

---

From: Mike Bishop <[email-masked]>
Date: Wed, 08 Mar 2017 16:10:31 -0800

4ce57c5  Without selecting?

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/171/files/dccd3f35ee751937b06f0ea48c8f1e342e79bab6..4ce57c568ce9abc7af842ff8f13b5c114944cee2

---

From: Igor Lubashev <[email-masked]>
Date: Wed, 08 Mar 2017 20:47:15 -0800

As discussed at length on the mailing list, I suggested what seemed like a minor improvement -- do not recommend sending RST_STREAM upon receipt of DISINTEREST, if your STREAM+FIN has already been ACKed.

This led to opening #370 with a suggestion to use max byte offset from STREAM/RST-STREAM frames for connection flow control instead of "sum-of-STREAM-except-RST_STREAM-is-special".

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/171#issuecomment-285253660

---

From: Martin Thomson <[email-masked]>
Date: Wed, 08 Mar 2017 20:56:48 -0800

I actually think that @marten-seemann is right to observe that accounting can (and should) use the last offset, but that's a separable issue.  It's good that we had the discussion.

What your suggestion does, @igorlord, is attach *actual semantics* to DISINTEREST.  This PR has basically no semantics.  Indeed, the message could be an HTTP-layer message (should it be?).  By allowing an endpoint to stop sending, this would add a rather complicated wrinkle to the stream state transition: if (peer has acknowledged the frame containing the last offset), then (receiving DISINTEREST closes the stream in that direction).  The other state transitions are all driven by the flow of packets in the other direction.  It's a fairly fundamental reduction in simplicity in exchange for not having to send a tiny frame.  That is, it saves some bytes by trading off complexity.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/171#issuecomment-285254767

---

From: Igor Lubashev <[email-masked]>
Date: Wed, 08 Mar 2017 22:14:39 -0800

I am also glad that something bigger than a resolution of this wrinkle already came out of this discussion.
> if (peer has acknowledged the frame containing the
> last offset), then (receiving DISINTEREST closes the> stream in that direction)
This is incorrect. The claim is not merely about "last offset" but "STREAM+FIN frame" -- a subtle but important difference here.   If (peer has acknowledged the STREAM+FIN frame), then the stream is already closed in that direction (by the virtue of sending that STREAM+FIN). DISINTEREST changes nothing.
But you are correct -- I am treating DISINTEREST as having semantics. The paragraph describing DISINTEREST states that the sender of DISINTERESTED *will discard all subsequent STREAM frames for this stream*. The PR uses a lower case "will", which I am treating as MUST. The PR could probably be more definite on this point, and if it is not a MUST, then my suggestion is wrong.
I do think that this feature belongs in transport. This signal is important for better utilization of bandwidth and resources. By having it in transport, this frame is exempt from flow control and can be delivered faster. Also, transport layer's library API must support this functionality anyway (stop buffering incoming data for this stream).

Sent from Yahoo Mail on Android 
 
  On Wed, Mar 8, 2017 at 11:56 PM, Martin Thomson<[email-masked]> wrote:   
I actually think that @marten-seemann is right to observe that accounting can (and should) use the last offset, but that's a separable issue. It's good that we had the discussion.

What your suggestion does, @igorlord, is attach actual semantics to DISINTEREST. This PR has basically no semantics. Indeed, the message could be an HTTP-layer message (should it be?). By allowing an endpoint to stop sending, this would add a rather complicated wrinkle to the stream state transition: if (peer has acknowledged the frame containing the last offset), then (receiving DISINTEREST closes the stream in that direction). The other state transitions are all driven by the flow of packets in the other direction. It's a fairly fundamental reduction in simplicity in exchange for not having to send a tiny frame. That is, it saves some bytes by trading off complexity.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/171#issuecomment-285264904

---

From: Martin Thomson <[email-masked]>
Date: Wed, 08 Mar 2017 23:01:27 -0800

I think that we have three choices:

1. this version: no real semantics, but still at the transport layer
2. move to HTTP on the basis that this is an HTTP special (I think that I'm somewhat swayed by @igorlord's arguments against doing this)
3. @igorlord's proposal of attaching semantics to this (which I remain opposed to on the basis of the complexity that it induces)

I think that this remains the best option.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/171#issuecomment-285271812

---

From: ianswett <[email-masked]>
Date: Thu, 09 Mar 2017 05:15:03 -0800

I strongly favor option 1.  

It's useful for every application I've come up with, so option 2 is not appealing and option 3 is more complex to implement.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/171#issuecomment-285348088

---

From: Igor Lubashev <[email-masked]>
Date: Thu, 09 Mar 2017 06:09:21 -0800

Could someone elaborate just a bit about the complexity of option 3? My understanding is that Option 3 is to only add the following semantics to DISINTEREST: "The sender of DISINTEREST MUST discard all currently buffered data and all subsequently received STREAM frames for this stream." Any implementation is probably doing this already, so the complexity added by codifying such semantics seems to be zero.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/171#issuecomment-285360541

---

From: Mike Bishop <[email-masked]>
Date: Thu, 09 Mar 2017 07:46:59 -0800

Currently, there’s no MUST, and that’s intentional.  Just like BLOCKED, DISINTEREST is a courtesy notification of something that is already happening, so that you can be smarter in response to it.

The complexity of Option 3 is that you go from:

·        Retransmit everything until you’ve sent RST_STREAM

·        If you send RST_STREAM, retransmit that, but nothing else
…to:

·        Retransmit everything until you’ve sent RST_STREAM or received DISINTEREST

·        If you send RST_STREAM or receive DISINTEREST, retransmit either RST_STREAM or the STREAM frame with the FIN bit

It doesn’t seem crippling, but it is an increase in complexity for (what seems to me) relatively limited benefit.

From: Igor Lubashev [mailto:[email-masked]]
Sent: Thursday, March 9, 2017 6:09 AM
To: quicwg/base-drafts <[email-masked]>
Cc: Mike Bishop <[email-masked]>; Author <[email-masked]>
Subject: Re: [quicwg/base-drafts] Independent states and DISINTEREST (#171)

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<https://github.com/quicwg/base-drafts/pull/171#issuecomment-285360541>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AEE2he3NfpZXMv3BMXBRp8-kw4hjVHKbks5rkAgRgaJpZM4LnL5T>.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/171#issuecomment-285388881

---

From: Mike Bishop <[email-masked]>
Date: Thu, 09 Mar 2017 17:28:33 -0800

I was going to agree that if you have to retransmit _something_, it might as well be RST_STREAM, because it's smaller.  But it's actually not.  A STREAM+FIN with no data is actually smaller than a RST_STREAM, because there's no error code and you get varlen fields for Stream ID and Final Offset.

I'm becoming less opposed.  I still question whether it's an improvement, but I no longer think it's worse.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/171#issuecomment-285545677

---

From: Igor Lubashev <[email-masked]>
Date: Thu, 09 Mar 2017 17:03:08 -0800

Attaching _semantics_ to DISTINCT (what sender of DISTINCT promises) and what ought to be done by the receiver of DISTINCT are two different things.  @martinthomson's choices were only about attaching semantics.

Now, if semantics are attached, we can examine the next question of whether that should affect the behavior.

The change of behavior would actually be to simplify:
- Retransmit everything until you’ve sent RST_STREAM
- Send RST_STREAM upon receiving DISINTEREST, unless RST_STREAM already sent or all data & STREAM+FIN have been ACKed

to:

- Retransmit everything until you’ve sent RST_STREAM or received DISINTEREST
- Send RST_STREAM upon receiving DISINTEREST, unless RST_STREAM already sent or STREAM+FIN has been ACKed

The "what to retransmit" behavior is unchanged (it is never proper to retransmit STEAM+FIN after receiving DISINTEREST).

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/171#issuecomment-285540683

---

From: Martin Thomson <[email-masked]>
Date: Thu, 09 Mar 2017 19:37:34 -0800

martinthomson commented on this pull request.

I'm making these comments on the assumption of choosing option 1.  There's a lot more to do if option 3 is chosen, particularly around the stream state machine.

> @@ -1599,6 +1601,32 @@ Final offset:
   data written on this stream by the RST_STREAM sender.

+
+
+## DISINTEREST Frame {#frame-disinterest}
+
+An endpoint may use a DISINTEREST frame (type=0x08) to communicate that incoming
+data is being discarded on receipt at application request.  This signals a peer
+to abruptly terminate transmission on a stream.  The frame is as follows:
+
+~~~
+ 0                   1                   2                   3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|                        Error Code (32)                        |

I don't think that we need an error code here.  If we do, and there are semantics attached to that code, then that's an argument to move this to the application protocol, where the semantics can gain context.

> @@ -2018,7 +2047,26 @@ implementations SHOULD treat the receipt of a frame that is not expressly
 permitted in the description of a state as a connection error
 ({{error-handling}}). Frames of unknown types are ignored.
 
-(TODO: QUIC_STREAM_NO_ERROR is a special case.  Write it up.)
+
+## Solicited State Transitions
+
+If an endpoint is no longer interested in the data being received, it MAY send a
+DISINTEREST frame on a stream in the "open" or "half-closed (local)" state to
+request closure of the stream in the opposite direction.  This typically
+indicates that the receiving application is no longer reading from the stream
+and all future data will be discarded upon receipt.

... "However, it doesn't imply a guarantee that the receiver will discard data, the sender still needs to either reset the stream or complete its transmission of data."

> +If an endpoint is no longer interested in the data being received, it MAY send a
+DISINTEREST frame on a stream in the "open" or "half-closed (local)" state to
+request closure of the stream in the opposite direction.  This typically
+indicates that the receiving application is no longer reading from the stream
+and all future data will be discarded upon receipt.
+
+STREAM frames received after sending DISINTEREST are still counted toward the
+connection and stream flow-control windows.  Even though these frames will be
+discarded, because they are sent before their sender receives the DISINTEREST,
+the sender will consider the frames to count against its flow-control windows.
+
+Upon receipt of a DISINTEREST frame, an endpoint SHOULD send a RST_STREAM with
+an error code of QUIC_RECEIVED_RST.  If the DISINTEREST frame is received on a
+stream that is already in the "half-closed (local)" or "closed" states, a
+RST_STREAM frame SHOULD still be sent and retransmission of previously-sent
+STREAM frames SHOULD be cancelled.

We gots to get us some MUST here.  This isn't squishy.  The only real exemption to needing a RST_STREAM here is if the stream is long done.  If the sender is still (re)transmitting anything, then it needs to either finish that or move over to (re)transmitting a RST_STREAM.  Otherwise we have a wrinkle on the state machine and I don't want that, even if it could save a RST_STREAM.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/171#pullrequestreview-25960065