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

STREAM_ID_BLOCKED frame can't encode being blocked on stream 0 #1850

Closed
marten-seemann opened this issue Oct 11, 2018 · 13 comments
Closed

STREAM_ID_BLOCKED frame can't encode being blocked on stream 0 #1850

marten-seemann opened this issue Oct 11, 2018 · 13 comments
Labels
-transport design An issue that affects the design of the protocol; resolution requires consensus. has-consensus An issue that the Chairs have determined has consensus, by canvassing the mailing list.

Comments

@marten-seemann
Copy link
Contributor

The STREAM_ID_BLOCKED frame has the Stream ID field which is

A variable-length integer indicating the highest stream ID that the sender was permitted to open.

This encoding doesn't allow to convey that the peer (in this case, this is always the client) would like to open stream 0, but the server didn't allow any bidirectional stream in the transport parameters (i.e. sent a 0 for initial_max_stream_data_bidi_remote).

The easy fix for this is to send the stream ID of the stream that the peer was not permitted to open due to missing stream flow control credit.

This would also have the nice property to make this frame more symmetric with the BLOCKED and STREAM_BLOCKED frames. For example, for STREAM_BLOCKED an offset of 0 means that the peer was not allowed to send byte 0 on that stream.

@janaiyengar
Copy link
Contributor

janaiyengar commented Oct 12, 2018 via email

@mikkelfj
Copy link
Contributor

Or we could finally decide that 0 is not a stream. 0 was invented for a reason.

@dtikhonov
Copy link
Member

Or we could finally decide that 0 is not a stream. 0 was invented for a reason.

Uh-oh -- not this can of worms again! 😄

@ianswett
Copy link
Contributor

+1 to 0 not being a stream from my perspective.

That being said, my understanding was that the question of 0 being a valid stream id(or 0 being a valid packet number) had clear lack of consensus, with about half the group wanting 0 to be valid and the other wanting to start at 1.

@marten-seemann
Copy link
Contributor Author

I agree that 0 should not be a stream, and that 0 should not be a packet number. It's really useful to have a sentinel value.
Making 0 a valid stream created a bunch of overhead in my code - nothing complicated, just a bunch of bools of stream 0 was already created or not.

@dtikhonov
Copy link
Member

I am with you about 0 being an invalid number for stream and packet numbers, @ianswett and @marten-seemann, and I also stated this on the mailing list. The (unofficial?) consensus seems to be 0, however. Should we be re-arguing the same issues over and over again?

@ianswett
Copy link
Contributor

Anything worth arguing once is worth arguing at least twice based on past experience in this WG.

@mikkelfj
Copy link
Contributor

mikkelfj commented Oct 12, 2018

The complication is that streams are modulo 4, so if 0 is invalid, so should stream 1, 2, and 3.

@marten-seemann
Copy link
Contributor Author

I am with you about 0 being an invalid number for stream and packet numbers, @ianswett and @marten-seemann, and I also stated this on the mailing list. The (unofficial?) consensus seems to be 0, however. Should we be re-arguing the same issues over and over again?

I don't think we ever even came close to establishing consensus on this issue, we just had some discussions during a coffee break at one of the interims.

The complication is that streams are module 4, so if 0 is invalid, so should stream 1, 2, and 3.

The stream directionality is defined mod 4. Starting at 1 is equally arbitrary as starting at 0.

@kazuho
Copy link
Member

kazuho commented Oct 12, 2018

I disagree to making 0 "special", because I care about having consistency in design. I do not care what is "natural."

Packet numbers, Stream IDs, stream offsets, MAX_DATA offset, all those things currently start from zero. Why do we need to start some of them from one? Doing so would be an unnecessary complexity.

As @marten-seemann points out, the issue here is MAX_STREAM_ID frame not following the design pattern we use for transmitting blocked state that we have for offsets. The fix should be to follow the pattern.

I agree that 0 should not be a stream, and that 0 should not be a packet number. It's really useful to have a sentinel value.

I understand that sentinel is useful. But it does not need to be zero. Because the "integers" we use in QUIC is uint62_t, you can use int64_t to represent the value internally, with -1 being the sentinel below and 262 being the one above.

@nibanks
Copy link
Member

nibanks commented Oct 12, 2018

I also disagree that 0 should be special. I feel like we've definitely had this discussion more than twice...

@janaiyengar
Copy link
Contributor

I suggest that we stick with @marten-seemann's original proposal for now, since it's a simple consistency fix. It also has the very useful property of not opening a can of worms.

@martinthomson
Copy link
Member

It's just not possible to leave you folks alone for any time, is it? I agree with @janaiyengar.

@martinthomson martinthomson added design An issue that affects the design of the protocol; resolution requires consensus. -transport labels Oct 16, 2018
martinthomson added a commit that referenced this issue Oct 19, 2018
Recent discussion around the use of BLOCKING frames highlighted some
inconsistency - and even disagreement - about what the purpose of the
frames are.  If you read through all the text for the flow
control-related frames, it is clear that the frame carries the *limit*
at the time the frame is sent.

> These frames always include the limit that is causing blocking at the
> time that they are transmitted.

This enacts that change more consistently, especially for
STREAM_ID_BLOCKED, which was the most unclear.

The discussion on #1851 suggested that there was value in knowing what
the sender (or stream opener) wanted to get to.  That is, the frames
would carry a higher value.  If the limit was X and the sender wanted to
send octet X+Y (or open stream X+Y), they would convey that information
instead.  The theory here is that the larger value (X+Y) would be sent,
allowing the receiver to make those resources available.

The problem with this alternative approach is that the value advertised
changes over time and it is difficult to connect the signal (a BLOCKED
frame), with the limit that was in force at the time.

I suspect that there is value in signaling the desired limits as well,
but that would require greater justification.  It also entails a change
and I'm leery of feature creep at this stage.

Closes #1851, #1850.
martinthomson added a commit that referenced this issue Oct 25, 2018
The problems we've been having with stream limits turned out to be
intractable without a larger shift.  This aligns stream limits with flow
control limits.  To do that, it takes two frame types, both for
increasing the limit and for signaling blocking.

Note that these frame types will be renumbered afterwards.  I realize
that this is a terrible arrangement, but it's temporary.  Ideally all
this limiting stuff is in a contiguous block.

Closes #1850.
@mnot mnot added the has-consensus An issue that the Chairs have determined has consensus, by canvassing the mailing list. label Mar 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
-transport design An issue that affects the design of the protocol; resolution requires consensus. has-consensus An issue that the Chairs have determined has consensus, by canvassing the mailing list.
Projects
None yet
Development

No branches or pull requests

9 participants