Re: Priority implementation complexity (was: Re: Extensible Priorities and Reprioritization)

Tom Bergan <tombergan@chromium.org> Fri, 19 June 2020 18:14 UTC

Return-Path: <ietf-http-wg-request+bounce-httpbisa-archive-bis2juki=lists.ie@listhub.w3.org>
X-Original-To: ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com
Delivered-To: ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id D90253A0CA3 for <ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com>; Fri, 19 Jun 2020 11:14:14 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.749
X-Spam-Level:
X-Spam-Status: No, score=-2.749 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, HTML_MESSAGE=0.001, MAILING_LIST_MULTI=-1, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=chromium.org
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id AlQG2KFm5iWl for <ietfarch-httpbisa-archive-bis2Juki@ietfa.amsl.com>; Fri, 19 Jun 2020 11:14:12 -0700 (PDT)
Received: from lyra.w3.org (lyra.w3.org [128.30.52.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id ADBBC3A0C9D for <httpbisa-archive-bis2Juki@lists.ietf.org>; Fri, 19 Jun 2020 11:14:12 -0700 (PDT)
Received: from lists by lyra.w3.org with local (Exim 4.92) (envelope-from <ietf-http-wg-request@listhub.w3.org>) id 1jmLTk-0002l2-Ax for ietf-http-wg-dist@listhub.w3.org; Fri, 19 Jun 2020 18:11:04 +0000
Resent-Date: Fri, 19 Jun 2020 18:11:04 +0000
Resent-Message-Id: <E1jmLTk-0002l2-Ax@lyra.w3.org>
Received: from mimas.w3.org ([128.30.52.79]) by lyra.w3.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from <tombergan@chromium.org>) id 1jmLTi-0002jS-90 for ietf-http-wg@listhub.w3.org; Fri, 19 Jun 2020 18:11:02 +0000
Received: from mail-oi1-x236.google.com ([2607:f8b0:4864:20::236]) by mimas.w3.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from <tombergan@chromium.org>) id 1jmLTf-00061B-GO for ietf-http-wg@w3.org; Fri, 19 Jun 2020 18:11:01 +0000
Received: by mail-oi1-x236.google.com with SMTP id a21so9218536oic.8 for <ietf-http-wg@w3.org>; Fri, 19 Jun 2020 11:10:59 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=TwRR8MGT4FGD0jYBkLIleZ91qN0fxIttfN4HKNeRZWU=; b=HwdAP74BUzJVHpPXVJUqXOhYYGZ5EQ9HP7jXleuaJ+jRjaje7t7UpcVgcFOVbmtAER UP3K8WsasNf909oKC2waDuLwU701UQwdjxTSDtuN0a6t5p+6x3BQWQL9FzoOUNJBkpjy usmfDFvzDX3XQpcjdzuo8svRLZ5lsyQFMXw+4=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=TwRR8MGT4FGD0jYBkLIleZ91qN0fxIttfN4HKNeRZWU=; b=JaZyOlbPIrUX8Foh4CpoAKtIYRVR3Fqyy9t872oYXJPcz+IEMF1wYB7GipLLyKGmpZ oZvQN5xLUFxXYPiu73BrsbBxLbgJK07kbxQu/3iGC839dVKkxJZmga3cjhENTLWA8cjG j0gZ/SCVYCrxF+sMWroV+uuGnebMwVYNb3TDCEK/4fgsi6TvzXQp0dX5Bk8iQPtb3zJo jtwr2uW5yW7IXs/VBx1EtQTgzC9Xto2605CXA6SrhVvi/nViNnF3g03nP5W+JCAmkCfK SHBJ0jmxmVDwPWJiJNagXlfacFUD76k8Sc22wHL79BGE7vVPdJXlK6Ui+I9LzNsfA/R9 QjdA==
X-Gm-Message-State: AOAM531ifUBIc64y3mcFhOsND61hBr2vxYLMoqQE7vuXcCUFqe80Yu0s qdzDXyWk8YS4UmoLNP05nTfr7Cm+9ZY=
X-Google-Smtp-Source: ABdhPJw8cm+ZBL9nH6tQeiKB5Ah6v/d2gW94E2DMFVbyqhXKTXN+nsgxstMkeObk3XdOCVQ8gkWSJg==
X-Received: by 2002:aca:cdc4:: with SMTP id d187mr4037617oig.117.1592590248147; Fri, 19 Jun 2020 11:10:48 -0700 (PDT)
Received: from mail-oi1-f173.google.com (mail-oi1-f173.google.com. [209.85.167.173]) by smtp.gmail.com with ESMTPSA id g51sm1512137otg.17.2020.06.19.11.10.47 for <ietf-http-wg@w3.org> (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 19 Jun 2020 11:10:47 -0700 (PDT)
Received: by mail-oi1-f173.google.com with SMTP id a3so9240994oid.4 for <ietf-http-wg@w3.org>; Fri, 19 Jun 2020 11:10:47 -0700 (PDT)
X-Received: by 2002:a05:6808:1c9:: with SMTP id x9mr4219405oic.16.1592590246495; Fri, 19 Jun 2020 11:10:46 -0700 (PDT)
MIME-Version: 1.0
References: <CALGR9obRjBSADN1KtKF6jvFVzNS1+JzaS0D0kCVKHKkd4sn+MQ@mail.gmail.com> <459C86F8-A989-4EF4-84DC-3568FF594F36@apple.com> <CANatvzwSpSHd7kZD-4tyMGkBJDdCBi6r_pLBvnaT8rrQy6SBHQ@mail.gmail.com> <CACMu3treK0m2mbpw9FebOjOcEed0bW-DbLbryHJH1DWAHoz+9g@mail.gmail.com> <CALGR9oZgE7ZfXdoYdUh9LUYC1fi8fMUyyTpvmV3GF7Z6Oxgg1g@mail.gmail.com> <20200609144428.GC22180@lubuntu> <CAJV+MGyuhxx=P6kZKktuREeq5pipZjxmwWP4jE_Sxhj_+krU2Q@mail.gmail.com> <CANatvzx_eg84V7UefOtSF+NHGHnTg7h-9n5bsRZRXxBqsaOkfQ@mail.gmail.com> <CACj=BEip6+7AunFsD=6qM5rsgrTfg6bRctOMu1gOe-KVjAW7Dw@mail.gmail.com> <CANatvzyv03VH9=+J=M2yY0EwCXp7HMWsXYaXOE=WYGDKBHdaVA@mail.gmail.com> <2C53D8AF-EFA8-42A3-9666-955A054468DB@greenbytes.de> <CACj=BEic2qzMXEfcsKS9CYnowChc-kMRjH66d3uKs+pqTz9Fug@mail.gmail.com> <4E0E8032-A903-46A2-A131-F1F4DE3CC037@greenbytes.de> <CACj=BEjOC-8S38U36Jw+Yb7yH_BZjxBkeLE6dLWH=8VMyBW80Q@mail.gmail.com> <ECF2C350-5D53-4E3B-9AAC-2F7E3FD4B528@greenbytes.de> <CACj=BEh53ZWj1UV6tNDaWPiuHbmbVmkYimu_rdYcYm06dZJAAQ@mail.gmail.com> <CAJV+MGzesbFRZFGK5SUM70HJrx3fdJ8AAGGqmwqDQhrL3eFmUw@mail.gmail.com> <CACj=BEiVPfOPGPuSu-tx5AovWwvTEwjCTqEooMq2muEteHZLAw@mail.gmail.com> <CAJV+MGyrKyhamN3WY+HE1i_0hKWQo6kuLe-6hO53YMrHPbto=w@mail.gmail.com> <CAM37g06T_U+Th83D7sH3S_LB-b_9TcaX5b9nDSFE8Z-x5U+c9A@mail.gmail.com> <CANatvzwEr97ec5h=YOZopFt2ou+vabthD+YMRwh0aESKy2jkkA@mail.gmail.com> <CAM37g05x7hZ=AfAicFHmPBxtz4VJhH14cCF2MKcRpfvq4_y1Cw@mail.gmail.com> <CALGR9oZdQnmdVo5hhA68r6CtRtDZUCRpBfbZjqQy=ggv9xmfeQ@mail.gmail.com>
In-Reply-To: <CALGR9oZdQnmdVo5hhA68r6CtRtDZUCRpBfbZjqQy=ggv9xmfeQ@mail.gmail.com>
From: Tom Bergan <tombergan@chromium.org>
Date: Fri, 19 Jun 2020 11:10:35 -0700
X-Gmail-Original-Message-ID: <CA+3+x5HRMOD_XRUpGRqFY=pttj=izswzSLdSDKuKXhAPCx6wfQ@mail.gmail.com>
Message-ID: <CA+3+x5HRMOD_XRUpGRqFY=pttj=izswzSLdSDKuKXhAPCx6wfQ@mail.gmail.com>
To: Lucas Pardue <lucaspardue.24.7@gmail.com>
Cc: HTTP Working Group <ietf-http-wg@w3.org>
Content-Type: multipart/alternative; boundary="000000000000eaafbe05a873cfc3"
Received-SPF: pass client-ip=2607:f8b0:4864:20::236; envelope-from=tombergan@chromium.org; helo=mail-oi1-x236.google.com
X-W3C-Hub-Spam-Status: No, score=-4.1
X-W3C-Hub-Spam-Report: BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, W3C_AA=-1, W3C_WL=-1
X-W3C-Scan-Sig: mimas.w3.org 1jmLTf-00061B-GO 057ae388cb9256dc4cb8a8785ab0562b
X-Original-To: ietf-http-wg@w3.org
Subject: Re: Priority implementation complexity (was: Re: Extensible Priorities and Reprioritization)
Archived-At: <https://www.w3.org/mid/CA+3+x5HRMOD_XRUpGRqFY=pttj=izswzSLdSDKuKXhAPCx6wfQ@mail.gmail.com>
Resent-From: ietf-http-wg@w3.org
X-Mailing-List: <ietf-http-wg@w3.org> archive/latest/37801
X-Loop: ietf-http-wg@w3.org
Resent-Sender: ietf-http-wg-request@w3.org
Precedence: list
List-Id: <ietf-http-wg.w3.org>
List-Help: <https://www.w3.org/Mail/>
List-Post: <mailto:ietf-http-wg@w3.org>
List-Unsubscribe: <mailto:ietf-http-wg-request@w3.org?subject=unsubscribe>

On Fri, Jun 19, 2020 at 9:26 AM Lucas Pardue <lucaspardue.24.7@gmail.com>
wrote:

> The server's role in optimizing the use of available bandwidth is an
> interesting perspective to take, especially considering the client's
> responsibility for providing flow control updates. In the basic HTTP/3
> priority implementation of the quiche library, the application processes
> the priority header and provides that information when sending response
> data. Internally the library uses an implementation-specific API method to
> set the priority of the transport stream; this does account for the
> properties Kazuho mentioned i) it returns an error if the stream ID exceeds
> current maximum ii) it no-ops if the stream ID refers to a closed stream.
> HTTP response payload data is written to each stream until the QUIC layer
> tells me it cannot take any more because the send window is full. In a
> separate loop, the QUIC layer selects stream data to transmit based on the
> priority. The client's expedience in providing flow control updates affects
> phase 1 (local buffering) but not phase 2 (emission). A client
> reprioritization would affect phase 2 not phase 1. In my case, quiche's
> transport priority method does account for the properties Kazuho mentioned
> i) it returns an error if the stream ID exceeds current maximum ii) it
> no-ops if the stream ID refers to a closed stream.
>
> The funnies will happen with trying to accommodate reprioritization
> signals:
>
>    - Exposing the reception of a reprioritization signal (PRIORITY_UPDATE
>    frame) to the application might be useful, or useless if we consider some
>    of Stefan's points.
>    - Reordering can cause the reprioritization to arrive before the
>    initial priority. Exposing an event to the application just made things
>    harder.
>       - Reordering isn't the only concern. In quiche, when an application
>       asks us to read from transport, we internally always read from the control
>       stream and QPACK streams before request streams. So we'd always pull out
>       the PRIORITY_UPDATE first.
>       - Exposing this scenario of reprioritization event to the
>       application is mostly useless because the application has no idea of what
>       is being reprioritized. If the priority is used for deciding server work,
>       one of the layers above transport needs to first validate and then remember
>       the details. This means that the library needs to expose a broader API
>       surface than it already does (e.g. exposing Kazuho's properties)
>       - If the transport layer API simply actions the last invoked
>    priority, naively calling it when the signals were received in the "wrong"
>    order means that reprioritization might be ignored.
>    - If a reprioritization event is simply hair pinned back into the
>    quiche library, there is an argument for not exposing it.
>    - I could simply accommodate things by modifying the transport
>    priority method to take a bool, is_initial. This would prevent an initial
>    priority from being applied after a reprioritization. In conjunction,
>    defining in the spec that initial priority is *always the header* would
>    remove some of the complexity of buffering data above the transport layer.
>
> All of this is additional consideration and speculation specific to my
> implementation, applicability to others can vary. I can see how things
> would be harder for implementers that attempt to manage more of the
> priority scheme in the HTTP/3 layer than the QUIC one.
>

I didn't follow those details. I think it would be helpful to summarize the
API you're referring to.

This might be naive: While there are potentially tricky implementation
issues, as discussed by Kazuho and Patrick earlier, and potentially tricky
scheduling decisions, as discussed by Stefan, I'm not seeing how those
translate into API problems. Generally speaking, at the HTTP application
level, a request doesn't really exist until the HEADERS arrive (example
<https://golang.org/pkg/net/http/#Handler>; all other HTTP libraries I'm
familiar with work in basically the same way). At that point, the request
has an initial priority, defined either by the HEADERS, or by the
PRIORITY_UPDATE, if one arrived before HEADERS and there's no Priority
field. Further PRIORITY_UPDATEs can be delivered with whatever event
mechanism is most convenient (callbacks, channels, etc).

We also haven't mentioned reprioritization of server push. The client
> cannot control the initial priority of a pushed response and there is an
> open issue about the default priority of a push [2]. In that thread we are
> leaning towards defining no default priority and letting a server pick
> based on information *it* has. However, Mike Bishop's point about
> reprioritizing pushes is interesting [3]. To paraphrase, if you consider
> the RTT of the connection, there are three conditions:
>
> a) the push priority was low: so no data was sent by the time a
> reprioritization was received at the server. It is possible to apply the
> reprioritization but importantly, the push was pointless and we may as well
> have waited for the client to make the request.
> b) the push priority was high, response size "small": so all data was sent
> by the time a reprioritization was received at the server. The
> reprioritization was useless.
> c) the push priority was high, response size "large": some data sent at
> initial priority but at the time a reprioritization is received at the
> server, the remaining data can be sent appropriately. However, anecdotally
> we know that pushing large objects is not a good idea.
>
> If we agree to those conditions, it makes for a poor argument to keep
> reprioritization of server push. But maybe there is data that disagrees.
>

FWIW, I have the opposite interpretation. We can't ignore case (a) by
simply saying that "the push was pointless and we may as well have waited
for the client". That assumes the server should have known the push would
be pointless, but in practice that conclusion depends on a number of
factors that can be difficult to predict (size of other responses,
congestion control state, network BDP). Sometimes push is useful, sometimes
it's not, and when it's not, we should gracefully fallback to behavior that
is equivalent to not using push at all. From that perspective, case (a) is
WAI.

This lack of a graceful fallback is a big reason why push can be such a
footgun. Frankly, if pushes cannot be reprioritized in this way, then IMO
push is essentially dead as a feature (and it's already on rocky ground, as
it's so hard to find cases where it works well in the first place).