Re: [alto] alto transport streams (Re: early reviews)

"Y. Richard Yang" <yry@cs.yale.edu> Mon, 25 July 2022 03:27 UTC

Return-Path: <yang.r.yang@gmail.com>
X-Original-To: alto@ietfa.amsl.com
Delivered-To: alto@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id ADA7EC15A735 for <alto@ietfa.amsl.com>; Sun, 24 Jul 2022 20:27:21 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.409
X-Spam-Level:
X-Spam-Status: No, score=-1.409 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, FREEMAIL_FORGED_FROMDOMAIN=0.248, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.248, HTML_MESSAGE=0.001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_ZEN_BLOCKED_OPENDNS=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, URIBL_BLOCKED=0.001, URIBL_DBL_BLOCKED_OPENDNS=0.001, URIBL_ZEN_BLOCKED_OPENDNS=0.001] autolearn=no autolearn_force=no
Received: from mail.ietf.org ([50.223.129.194]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id L0c7b_8Ar9XK for <alto@ietfa.amsl.com>; Sun, 24 Jul 2022 20:27:17 -0700 (PDT)
Received: from mail-yw1-f178.google.com (mail-yw1-f178.google.com [209.85.128.178]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id CD854C15A728 for <alto@ietf.org>; Sun, 24 Jul 2022 20:27:17 -0700 (PDT)
Received: by mail-yw1-f178.google.com with SMTP id 00721157ae682-31e47ac84daso96667257b3.0 for <alto@ietf.org>; Sun, 24 Jul 2022 20:27:17 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=x6lKpwJbmcDvT7fR19GhY13BYvDqF4bC8NKVBnqAJMI=; b=bxbv847c1HXljP4l2btauBQkTyViUWY1DQD5u8uMwapFps20QR2bfnLTgjdSbjdHAe zyyM/z/JvFk1ruWRt/D1bEn456PE/6rw5BZ5wZf4zIPJW+48xhtStNg8ADIxynC+X/gL X6GnB0GozfcKfEm2j34fHesUnzxImeTV0V5i4VIw7P/02CgdqQGuGjdTvYn1Uxv2ut0+ HGwWU0c2o6qYQsVdDQmfFwrliI86hmcvaszPzDXVoC2l4ctI8ByQwKuJLz0g8pkEfI2I pfXxF5LvPKLkRVqqLxtDG6WME++kjtV5bRjt/Iozlx9d90OoDLZu9g97HxtqpUiUwRjf qb3w==
X-Gm-Message-State: AJIora8X3YEE+AW2ksc789pJtOTID/txBXgHNUBzrioSfX0oblmpDE7N TnNRGfTa0l7vBvwxZx8qotpcLsIqRw670/vw7A0=
X-Google-Smtp-Source: AGRyM1vHeGoZcjMLeFXNTxYYe/BBGPZyfjd70MKGmfbeUFB5GqPuI94jluR7YLJFAsOlYSP6b4MoYaxHpHNll6/GDBY=
X-Received: by 2002:a0d:cf84:0:b0:31e:7901:19e9 with SMTP id r126-20020a0dcf84000000b0031e790119e9mr8668717ywd.7.1658719636888; Sun, 24 Jul 2022 20:27:16 -0700 (PDT)
MIME-Version: 1.0
References: <CANUuoLoGYYO3PczKzCyvnrNoqGUa0Zfn8rr-x+Hz2dzqLFBVww@mail.gmail.com> <EF370A5A-1005-4F81-98F8-CB7117B9513F@mnot.net>
In-Reply-To: <EF370A5A-1005-4F81-98F8-CB7117B9513F@mnot.net>
From: "Y. Richard Yang" <yry@cs.yale.edu>
Date: Sun, 24 Jul 2022 23:27:05 -0400
Message-ID: <CANUuoLrvFMDDaY+o4FF=q_evbH+NfsNNb_3y98i-NvC0wzFhOQ@mail.gmail.com>
To: Mark Nottingham <mnot@mnot.net>
Cc: Spencer Dawkins <spencerdawkins.ietf@gmail.com>, Martin Duke <martin.h.duke@gmail.com>, IETF ALTO <alto@ietf.org>
Content-Type: multipart/alternative; boundary="000000000000bd217e05e498c2d0"
Archived-At: <https://mailarchive.ietf.org/arch/msg/alto/IxMytOqXyiGg9KugPWU3FEW480k>
Subject: Re: [alto] alto transport streams (Re: early reviews)
X-BeenThere: alto@ietf.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: "Application-Layer Traffic Optimization \(alto\) WG mailing list" <alto.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/alto>, <mailto:alto-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/alto/>
List-Post: <mailto:alto@ietf.org>
List-Help: <mailto:alto-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/alto>, <mailto:alto-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 25 Jul 2022 03:27:21 -0000

Hi Mark,

Thank you so much for the quick feedback. Sorry for the delay as we were
traveling ...

Please see below.

On Thu, Jul 21, 2022 at 11:00 PM Mark Nottingham <mnot@mnot.net> wrote:

> Hi Richard,
>
> I'm just going to give some impressions while reading this, FWIW.
>
> > On 22 Jul 2022, at 6:20 am, Y. Richard Yang <yry@cs.yale.edu> wrote:
> >
> > Hi Mark, Martin, Spencer,
> >
> > First, thank you so much for the reviews. Sorry for the delay in
> responding asap, due to summer and travel.
> >
> > One common comment we see from all three of you, in different texts, is
> essentially on the service model of the current document (
> https://datatracker.ietf.org/doc/draft-ietf-alto-new-transport/): how
> much control on the ordering of the messages (Mark/Martin), in-order or not
> (Spencer). Hence, after the meeting early morning today, we feel that we
> should start a single thread to discuss this issue. We will send a summary
> of our responses to each of your individual reviews later.
> >
> > To help make clear the problem and the current design, let's start by
> summarizing the transport model of ALTO/SSE (RFC8895;
> https://datatracker.ietf.org/doc/html/rfc8895). We will state the problem
> as abstract as possible to see the essence of the problem and the potential
> design choices:
> > - P1: A server offers multiple resources R = {R[1], R[2], R[3], R[4],
> ...}, where each R[i]i is represnted by a URI;
>
> Good so far; that's pretty much a description of every use of HTTP.
>
> > - P2: A client can request from the server the monitoring of a subset M
> of the resources: M \subset R, e.g., M = {R[1], R[2], R[3]}; for example,
> R[1] is a network map, R[2] is a cost map using the network map R[1], and
> R[3] is an endpoint property map; for simplicity, assume the requested
> resources numbered 1 to |M|
>
> So, in HTTP terms, that would be creating a new resource whose semantic is
> "I am a monitor for  _this_ set of resources". The tricky party here is how
> to realise that in terms of HTTP -- i.e., what does a GET response look
> like?
>
> One answer would be a feed format like RSS or Atom. Do you support GET in
> this fashion?
>

A new resource whose semantic is "I am a monitor for  _this_ set of
resources" is a good term to use. In the current design, we refer to it as
the transport queue: the request (using POST, to provide parameters)
returns a URI to the (transport queue) resource. Make sense?

> - P3: The server can push a sequence of incremental updates to the client
> for each resource in M. Denote {U[i,1], U[i,2], ...} as the update sequence
> from the server to the client for R[i] in M, where U[i,1] is the first
> response for the requested resource R[i], U[i,2] is an incremental update
> (patch) on top of U[i,1], U[i,3] is the incremental update on top of
> U[i,2], ...
>
> Here's where I get more concerned. Server Push is unproven, and indeed has
> been shown to be an anti-pattern for its originally intended use case.
> Folks are still interested in it for API use cases (and I'd see this as one
> of those), but it's still very wild west, with no real widespread
> deployment experience that I'm aware of. See especially <
> https://httpwg.org/specs/rfc9205.html#server-push>gt;.
>
> The first question I'd ask here is whether polling a resource (like a feed
> document) is sufficient. That pattern works very well with HTTP, and is
> well-understood -- _much_ more so than Server Push.
>
> The downside, of course, is latency, but it's not unknown to deploy
> applications with very high polling frequencies (e.g., 1/s). Have you
> considered this approach? Would modifying it to long-polling (where the
> client always keeps a request 'hanging' until the server has an update)
> help? Keep in mind that with HTTP/2 and above, long-polling has very few
> downsides.
>

This is an excellent comment! We looked at the current design, and see that
integrating long poll is quite clean, easy-to-add. In particular, the
current design is to provide an incremental update queue, which provides
the seq numbers; an example of the updates queue is the following:
{
          [
            {“seq”:        101,
             "media-type": "application/alto-costmap+json",
             “tag”:        "a10ce8b059740b0b2e3f8eb1d4785acd42231bfe" },
            {“seq”:        102,
             "media-type": "application/merge-patch+json",
             “tag”:        "cdf0222x59740b0b2e3f8eb1d4785acd42231bfe" },
            {“seq”:        103,
             "media-type": "application/merge-patch+json",
             “tag”:        "8eb1d4785acd42231bfecdf0222x59740b0b2e3f",
             "link":       "/tqs/2718281828459/snapshot/2e3f"}

          ],
       }

A hanging long poll is to allow a request on the next seq; for example, it
is to allow the request to 104,
/tqs/2718281828459/uq/104

To make it fully functional, the client should indicate the ability to
accept all potential media types from the base media type and the potential
incremental types.

We plan to add this capability,

>
> Another option would be to invert the relationship and have what's
> currently the server open connections to the current client and PUT / PATCH
> updates to them. Much more natural HTTP, but of course you need an identity
> for the client and a clear path to it. This approach also has considerable
> deployment experience (commonly known as 'webhooks').
>
>
This is another excellent, intriguingly interesting suggestion. We looked
at the current design carefully. From a syntax point of view, it is a
straightforward design: changing the request from PUSH_PROMISE to PUT, at
the correct seq; for example, see the example in Sec. 6.2. A benefit of
this design is that we then can get rid of the following requirement: "Push
management: The client MUST NOT cancel (RST_STREAM) a PUSH_PROMISE to avoid
complex server state management." (the text right before Sec. 6.2).

The main conceptual issue of this design, however, is semantics.
Conceptually, the state is at the server, and the protocol is to transfer
the state from the server to the client. With the reverse design, the state
is (persisted) at the client. We overall like the idea and plan to discuss
it in the WG meeting more.


> > - P3.1: For flexibility, each U[i,j] can choose its own encoding; for
> example, U[1,1] is application/alto-networkmap+json, U[1,2] is
> application/merge-patch+json; concrete examples please see the current
> draft (search "Promised Stream 4" and "Promised Stream 6")
>
> Sure.
>
> > - P4: Consider the dependency among the information resources in P3:
> {U[1,1], U[1,2], ...}, {U[2,1], U[2,2], ...}, and {U[3,1], ....}. There are
> two types:
> > - P4.1 We have that U[i,j+1] depends on U[i,j] due to incremental
> updates---in the general case, the client needs to have received and
> processed U[i,j] to apply U[i,j+1], unless U[i,j+1] is a snapshot (not an
> incremental update).
>
> Right. The closest things that we have for managing this sort of thing in
> HTTP today are conditional requests; e.g., If-Match.
>
> > - P4.2 It is possible that U[i', j'] depends on U[i, j], where i' != i:
> for example, a cost map depends on the correct version of the network map.
>
> That's a purely application-level semantic, correct? I.e., resource A
> isn't useful without resource B, and furthermore representation 1 of
> resource A requires representation 4 of resource B to be interpreted
> correctly. This is similar to issues that people face in caching CSS,
> JavaScript and the like today -- generally it's solved by giving
> representations with breaking changes different URLs, and referencing them
> directly from their dependants. We've talked about other ways to solve
> this, but that's current practice.
>
>
This can be a good place to discuss a bit more on application semantics and
get your opinion on how much the semantics is conveyed to the transport
layer (e.g., explicitly indicated in HTTP stream dependencies/priorities in
HTTP-understood header fields).

Consider a set of resources {Ui} with application-level dependencies (e.g.,
U1 -> U2, U1 -> U3, U3 -> U4). I see two transport-oblivious designs:
- Transport oblivious, batch submission: U1, U2, U3 and U4 are submitted to
the (HTTP) transport (buffers) concurrently. Without knowing the
dependencies, the transport may schedule the transfers in the order of U4,
U3, U2 and U1, resulting in application layer latency.
- Transport oblivious, controlled-release submission: app submits U1; and
when U1 is transferred, submits U2/U3 (i.e., those at the roots of the
DAG); after U3 is transported, submit U4. This will avoid priority reversal
but a problem is that if the TCP congestion window is large enough to
accommodate all U1-U4, it helps to submit all all.

Any previous work/techniques?


> > If one goes academic, there is a dependency graph that can describe the
> dependencies.
> >
> > In RFC8895, since it is a single HTTP connection, all of the {U[i,j]}
> are *linearized" by the server into a single sequence, and Section 6.7 of
> RFC8895 specifies the linearization (serialization) requirements (P4.1 and
> P4.2). As we know from concurrency control, linearization is strong and
> leaves performance on the table. One of the motivations for the new
> document is to take advantage of the more relaxed concurrency model allowed
> by HTTP/2 and HTTP/3.
> >
> > So what are the design points that the design team has considered:
> >
> > - D1 (linearization): the server pushes all {U[i,j]} in a single stream.
> Due to P3.1, there must be an internal structure to separate the U[i,j]
> boundaries and different U[i,j] can have different media types, leading
> back to RFC8895.
>
> I don't understand why it's necessary to do this. AFAICT there are no
> ordering constraints created by state-changing operations; rather, you just
> have dependencies that can be resolved once all of the updates are
> available.
>
> Yes.


> For example, if you *are* going to stay with Server Push, I immediately
> wonder what the value of having a monitor resource is, rather than just
> having the appropriate resources push updates directly using their own
> identity. Of course you still need some sort of subscription mechanism, but
> that doesn't mean that the actual updates need to be coalesced into one
> HTTP response.
>
>
The monitor resource (update queue) is to allow both client pull and allow
a client to see the push status.


> >
> > - D2 (max concurrency): Each U[i,j] is sent in an independent
> (concurrent) push stream (and hence can use its own media type as it is)
> and let the application-layer handles dependency: ALTO has a build-in
> dependency check for cross-resource (P4.2) and the sequence numbers of
> incremental updates allow application (ALTO client) to figure out the
> same-resource dependency (P4.1). The application (ALTO client) buffers all
> streams to realize the ordering.
>
> Right, this seems more reasonable, although again I wonder about the use
> of Push.
>
> > - D3 (max concurrency with server barrier): It is D2 but requires that
> the server does not push U[i',j'] if there is a U[i,j], s.t., (1) U[i,j] is
> still being sent by the server to the client and (2) U[i',j'] depends on
> U[i,j].
> >
> > The intention of the current document is to reflect D3. Note that for
> D3, the ALTO client still needs to handle the dependency correctly, as the
> streams may be only buffered at the kernel, and not processed. But the
> benefit of D3 over D2 is that it implements essentially some flow control,
> to avoid a faster server overwhelming a slower client.
>
> The streams might be buffered anywhere in the handling chain.


Yes. Good comment.



> Given that H2/H3 already have flow control, is this really necessary? Or
> are you trying to manage buffer sizes 'above' the HTTP layer?
>

A main consideration was to influence the scheduling---see the
application-layer semantics discussion.



>
> > One design point that one may consider is
> > - D4 (linearization of same resource and concurrency for different
> resources): the U[i,j] of the same R[i] is sent in the same stream (and
> hence linearized); this can be a reasonable design, but due to P3.1, it is
> still not clean; see D1 discussion.
>
> Indeed.
>
> > I hope that the preceding has clarified the stream control issue that
> the design faced. One can see that the issue can be considered as a generic
> issue--what to specify when embedding one concurrency model (P4.1/P4.2)
> into a given concurrency structure (HTTP/2 or HTTP/3). We took a quick look
> at DoH. It looks that the dependency model of DoH might be simpler: there
> is no same-resource (DNS resource type) due to no incremental updates (DNS
> update model appears to be the idempotent overwrite model) or
> cross-resource dependency. Please correct us if we have missed it.
> >
> > The current document tried to separate the issue into Sec. 8 (ALTO/H2
> Stream Management). One way forward we can see is to (1) only specify that
> each U[i,] is mapped to its own stream (to handle P3.1), and (2) not
> specify the dependency among U[i,j] (i.e., specify as close as possible to
> specify nothing) and let the client figure out the dependency at the
> message; we add the requirement language such as "The client MUST check the
> dependency ...;"
>
> Overall, this seems like a very awkward layering of an application onto
> HTTP. I don't know enough about the underlying requirements to tell whether
> a more natural approach is possible today, but I suspect it might be.
>
> Being able to get updates to the state of a set of resources is a pretty
> common requirement, so I'd very much like to see this addressed in a
> generic way that's both reusable for other applications and that works well
> with the other parts of HTTP. I wrote a little more about this here: <
> https://www.mnot.net/blog/2022/02/20/websockets>gt;.

Another thing that comes to mind is that what you're trying to do seems to
> have _some_ overlap with what the BRAID folks are trying to do: <
> https://datatracker.ietf.org/doc/html/draft-toomim-httpbis-braid-http>gt;.
> I'd be very interested to hear if you thought it'd be helpful to have that
> document move forward.
>
>
Thank you so much for these two pointers and we will take a look shortly
and share the thoughts soon.


> Hope this helps,
>

This is fantastically helpful and enlighening. Thank you so much!

Richard


>
>
> --
> Mark Nottingham   https://www.mnot.net/
>