Re: Stuck in a train -- reading HTTP/2 draft.

On 18 June 2014 06:28, Poul-Henning Kamp <phk@phk.freebsd.dk> wrote:

> Martin Thomson writes:
>
> >>> It's also pretty non-obvious why we need CONTINUATION in the
> >>> first place:  Why not simply send HEADERS until one of them has
> >>> the END_HEADERS bit set ?
> >
> >
> http://http2.github.io/faq/#why-the-rules-around-continuation-on-headers-frames
>
> I'm not asking why we need multiple frames, that's painfully obvious
> when the cookie mistake is retained.
>
> I'm asking why the frames have different names ?
>
> Rather than
>
>         HEADERS
>         CONTINUATION * N
>         CONTINUATION + END_HEADERS
>
> I would do
>
>         HEADERS * N
>         HEADERS + END_HEADERS
>
> Since I don't see how CONTINUATION differs from HEADERS in any way
> other way than name and type number.
>
>
Actually, when you account for things like stream dependency (which
shouldn't be included in continued headers), and continuations on
PUSH_PROMISE, you end up with:

    HEADERS
    [HEADERS - PRIORITY] * N
    HEADERS - PRIORITY + END_HEADERS

    PUSH_PROMISE
    [HEADERS - PRIORITY] * N
    HEADERS - PRIORITY + END_HEADERS

That's pretty complicated. I've also ignored padding, which is currently
not included in CONTINUATION frames. (Note: I've made PP followed by H
because subsequent PP frames would waste four bytes on the promised stream
id.)


Eliminating one frame type would simplify the RFC text and
> implementations, (Ref: Antoine de Saint Exupéry's wisdom that
> "Perfection is finally attained not when there is no longer anything
> to add, but when there is no longer anything to take away.")
>
>
That quote also applies to the DRY principle, and not all of us are
pretending PUSH_PROMISE doesn't exist.



> >>> Page 36: SETTINGS synchronization
> >>> ---------------------------------
>
> >That's not true.  You send SETTINGS, you carry on.  You only lose RTTs
> >if you want to apply tight limits and then open them again.
>
> 99% of those ACKs will be ignored.
>
> I propose that the remaining 1% could get the exact same functionality
> by sending SETTINGS + PING and wait for the pong.
>
> That means less wasted bandwidth, less RFC text and less implementation
> source code.
> ​​
>
>And the explicit acknowledgement allows for different implementation
> >strategies.
>
> Using PING to get the acknowledgement and only when the strategy
> actually calls for an ack, while saving RFC text and source code
> gives you the same flexibility.
>
> ​
Your preference seems to be for reusing and overloading existing frames,
while personally I find the current approach (single-purpose, single-use
frame types) simpler. That's a taste issue, so we're allowed to disagree,
and neither is "better."

If you want to prioritise bandwidth, we could add a new "SEND_ACK" flag to
SETTINGS. It doesn't add much complexity, and it saves traffic on all those
unneeded 8-byte ACKs.

Incidentally, PING/PONG costs an extra 16 bytes each way, while
SETTINGS/ACK costs 0+8, so for the cases where you do care about the
acknowledgement, ping is a relative waste of bandwidth.



> >>> Page 51:  To strict ordering ?
> >>> ------------------------------
> >>>
> >>>   Other frames (from any stream) MUST NOT occur between either HEADERS
> >>>   frame and the following CONTINUATION frames (if present), nor between
> >>>   CONTINUATION frames.
> >>>
> >>> Isn't this needlessly strict ?  No harm would come from DATA frames
> >>> or SETTING frames being stuffed in there.
> >>>
> >>> All this trouble could be avoided by only submitting headers for
> >>> decompression, as a unit, when the END_HEADERS have been received.
> >
> >That creates a nice state exhaustion/denial of service opportunity
> >that we decided not to permit.
>
> I really don't understand that answer:  Buffering the compressed
> header will take up less space than buffering the uncompressed
> header ?
>
>
Who's buffering headers? The whole point is that we're streaming them
through the HPACK context, *not* buffering them.

Well, you might be buffering them, if your API emits headers to the
application in a single blob, rather than streaming them up. That's nothing
to do with the spec, though.



> >>> Page 51: Gibberish
> >>> ------------------
> >>>
> >>> This needs to be translated to human readable form:
> >>>
> >>>   Otherwise, frames MAY be interspersed on the stream between these
> >>>   frames, but those frames do not carry HTTP semantics.  In particular,
> >>>   HEADERS frames (and any CONTINUATION frames that follow) other than
> >>>   the first and optional last frames in this sequence do not carry HTTP
> >>>   semantics.
> >
> >Improved text gratefully accepted.
>
> I'd happy attempt if I had any idea what it atttempts to say, but I
> literally looked a that paragraph for 10 minutes without finding out.
>
> If nobody else knows, you should strike it.
>
>
I wouldn't do much to change it, just some minor disambiguation:

```
   ​Otherwise, frames MAY be interspersed on the stream between these
header blocks and DATA frames, but those interstitial frames do not carry
HTTP semantics. In particular, interstitial HEADERS frames (and any
CONTINUATION frames that follow) do not carry HTTP semantics.
```

Personally I'd really like someone to add something there to explain what
non-semantic metadata _means_, maybe with an example. This could also clear
up some of my residual issues with segments.


[Second message:]


>​>> >> I would allocate frame Type values so that the top bit indicates
​>​
>> >> "subject to flow-control" to simplify implementation.  Similarly
​>​
>> >> expending a bit to mark hop-to-hop frames would make life easier
​>​
>> >> for high performance implementations.
​>​
>>
​>​
>> SPDY effectively did that.  Given the status quo, I'm not sure that
​>​
>> (!type) and (type&mask) are measurably different performance-wise.
​>​
>>
​>​
>Wouldn't play nicely with extension frames; you'd need more rules about how
​>​
>to forward unrecognised end-to-end frame types (not currently possible),
​>​
>how to detect/mitigate jerks working around flow control ... actually, I
​>​
>thought extension frames were all flow controlled, but apparently not. We
​>​
>rely on extension authors to be honest and accurate about what extension
​>​
>frames are flow-controlled.
​>
​> ​
Encoding it in the allocated type would make that honesty automatic,
​> ​
and life easier for high-speed implementations.

No, I think it's easier now: unrecognised types are never forwarded, and
unrecognised types are not flow-controlled. That's pretty simple. Not as
useful as it could be, but simple.


​>​
>> >> Page 50: Error messages
​>​
>> >> -----------------------
​>​
>> >>
​>​
>> >> The RFC should propose text-messages for presentation purposes
​>​
>
​>​
>The equivalent of reason phrases attached to status codes, or something
​>​
>richer?
​>​
​> Something your grand-aunt can read to you in the phone, but preferably
​> ​
have a chance of understanding so she doesn't have to.
​>
​> ​
My fear is that she'll call and ask what she should do about:
​>
​>​
        "My computers says says: REFUSED_STREAM: The endpoint refuses
​>​
        the stream prior to performing any application processing"
​>
​> ​
That's a prefectly good explanation for the programmer, but not for
​> ​
an end user.  Experiences has shown that most programmers don't realize
> there is a difference unless we make them aware of it.​

That's true, but I'm pretty sure we're not in the business of designing UI
(and error messages are UI). And I, for one, do not want to be in any way
associated with any L10n of error messages, or the politics of "why are
they only in English?" or "why are they not in Swahili?"


-- 
  Matthew Kerwin
  http://matthew.kerwin.net.au/

Received on Tuesday, 17 June 2014 23:39:51 UTC