httpwg / http-extensions

HTTP Extensions in progress
https://httpwg.org/http-extensions/
427 stars 141 forks source link

Prioritization of concurrent uploads #2242

Open LPardue opened 2 years ago

LPardue commented 2 years ago

HTTP uploads aren't new, so thinking about prioritization of concurrent uploads should not be either. I think its worth asking the question because we might be able to come to a quick answer.

I do think resumable uploads offers some interesting new possibilities to clients to manage their workloads. For example, with robust resumption, it becomes far more practical to explicitly abort an upload in order to allocate sending resource to something else.

Imagine a scenario where a user wants to transfer some items to their cloud storage: they start with a large video file, and then decide to upload a small text document. The user is doing this because they need the small file to be synced ASAP to some other device, via the cloud. If the client allocates more upload resources to the large file, the timeliness to deliver the small object is affected.

There are several options here, ones that spring to mind:

a) support local client indication of priorities of uploads. The user agent can use this information for resource scheduling decisions at the HTTP or transport layer. E.g., if a small file is marked as higher priority, send it ahead of the video

b) client pre-emption of transfers via request cancellation. The user agent is told to terminate other uploads, free resource for their preferred upload. The impact of this approach is cheaper compared to non-resumable uploads especially if you're uploading over H2 or H3 where streams are cheap. However, it might be disruptive to the server side of things, causing them to deal with more resumptions than they might anticipate.

c) do nothing and let implementations figure it out on their own

Option (c) seems not ideal because the easiest thing to do is nothing. In many deployments, upload bandwidth is a scarce resource. If we do (c), users might just fall back to (b) any way out of frustration.

martinthomson commented 2 years ago

Is this an API issue more than a protocol one? If you want option (a), then doesn't that depend on specifying a common API where users of a client stack can tell that stack how to prioritize sending? Many - or even most - HTTP/3 implementations support that sort of API internally, as do many HTTP/2 implementations. But exposing the signal to applications in browsers is not yet a thing. It could be, but various efforts are ongoing.

Related to this, I can't really see much value in server-driven prioritization in this case, but that could just be a lack of imagination on my part.

LPardue commented 2 years ago

Yes this could just be a case of resolving the issue with no action or a sinple statement like "its an implementation matter related to underlying wire version details".

I'm curious though whether we need to say more - somewhere - because we are aiming to enhance client upload behaviour and people might actually start to do more of it and faceplant.

Im also curious if there is any case where we might agree propagating signals could help. For instance if we expect that the server handling the upload has a good chance of talking to an upstream, never passing on what the client is doing locally might interfere with its performance objectives. To me, that rings true for any client data generation including WebTransport. But if I'm in the rough here, I'd like to establish that sooner rather than later.

martinthomson commented 2 years ago

"Our" responsibility might end at simple language if you define the scope to be this draft, but adjustments to fetch or other APIs aren't out of scope for a larger effort.

the server handling the upload has a good chance of talking to an upstream

Oh, I was thinking about signals from server to client. That is, maybe the server knows that it needs one file ahead of another and can give the client information about those needs.

You were thinking of the client telling the server what it is doing so that the server can propagate that. For an intermediary, that makes a lot of sense, especially if it is ignorant of both client and resource specifics.

For that case, I think that our existing signals might suffice for that. After all, though we say that it "indicates the endpoint's view of how HTTP responses should be prioritized", prioritizing a response depends on all that comes before it, so maybe you could implicitly extend it to cover request delivery and processing.

LPardue commented 2 years ago

For that case, I think that our existing signals might suffice for that. After all, though we say that it "indicates the endpoint's view of how HTTP responses should be prioritized", prioritizing a response depends on all that comes before it, so maybe you could implicitly extend it to cover request delivery and processing.

Yeah pretty much this sort of thing might give enough wiggle to make work. And is part of the reason that I think employing a compatible* prioritization scheme in WebTransport would mean we could get a cohesive ecosystem without too much extra pain.

kazuho commented 2 years ago

I might point out that RFC 9218 section 9 explicitly states that a client can use the priority header field for scheduling the requests that it initiates.

Regarding sending signals from client to intermediaries, I think that's an interesting use case, though I wonder how much we need such signal. Scheduling is required only if the bandwidth between the client and the intermediary is wider than that between intermediary and origin. My guess is that mostly the bottleneck would be between the client and the intermediary, and that is the case where the users actually suffer.

Regarding sending signals from the server, I would point out that flow control can be and is used for controlling the order in which the client sends requests with large bodies. IMHO, prioritization as indication is an user-experience issue. But in case of server driven signalling, what we want is enforcement, and that's why we have been using flow control.

LPardue commented 2 years ago

I might point out that RFC 9218 section 9 explicitly states that a client can use the priority header field for scheduling the requests that it initiates.

Yeah. That's pretty all encompassing, if maybe not 100% clear to implementers on what to do. The struggle might be mostly in the local API surfaces. To go back to MT's reference to fetch and priority hints, we might benefit from some engagement to understand how the web platform schedules uploads today. The upload case might be just fine with the three levels that priority hints provides - low, default, high. A general indication like this still gives implementations a lot of flexibility - for instance, if a low priority upload failed at 99%, one might issue the request to repair the final 1% at high priority. That's implementation strategy we probably don't need to standardize in the protocol.

My guess is that mostly the bottleneck would be between the client and the intermediary, and that is the case where the users actually suffer.

This is a pretty astute observation - the bottleneck is important. I could imagine many deployments of uploads get handled by a destination in a datacentre that is well connected and is not a bottleneck. It's more like an infinite sink that will allow an intermediary to propagate the client's send scheduling implicitly.

However, I could imagine some scenarios where timeliness of delivery is important (more so in WebTransport, which is a tangent I admit). I would expect there to be some cases where the client->edge hop is actually short, while the edge->origin is a long fat pipe. For the intermediary, if its balancing low and high priority items, the RTT(s) required to get to the point of sending the very urgent bytes of a file might be be a problem. We sort of fix this in the download direction with tcp lowat. Wonder if trying to tune that in the upload direction is achievable or hard due to differences.