Re: What error code when concurrent stream limit is exceeded

On Mon, Nov 24, 2014 at 08:51:52AM -0800, Brad Fitzpatrick wrote:
> To imagine an absurd example, an HTTP/2 client could just write random
> bytes to the socket from random threads and hope to get an HTTP/2 response.
> HTTP/2 requests are small enough, this strategy will eventually work. It's
> not a good strategy though.

What I mean is that we're not necessarily talking about designing new
products but adapting existing H/1 products to H/2. One of the goals of
H/2 was to be able to adapt existing products, and many users will simply
think that only the encoding changes. I'm already seeing users maintain
connection pools in H/1 (very common in contexts of WebServices) and I
reasonably expect that these users will try to map their architecture
onto H/2. Such users will not necessarily realize that their concurrency
limit which is currently enforced by the number of tasks/threads/connections
or whatever will not necessarily be respected when they move to a shared
encoder which picks H/1 streams one at a time and encodes them to H/2 until
the output buffer is full.

> Slightly less absurd is to have a "totally asynchronous set of streams in
> certain tasks (say a thread per stream)" all speaking mostly-valid HTTP/2,
> only using a lower level to coordinate access to the socket, but not
> coordinating actions such as "hey, this is thread wants to open a stream...
> am I allowed to?" It's still not a good strategy. It might look like HTTP/2
> at the frame level, and usually get lucky, but if it can't count basic
> things and track what all its threads are doing, things like violating
> MAX_CONCONCURRENT_STREAMS won't be its only problems.

Don't get me wrong : I'm not trying to encourage bad use, I'm just suspecting
that we'll see a number of corner cases people do not expect at all. We're
already seeing exactly the sames with TCP and local source ports because
users don't know what an orphan is, and don't understand how they can run
out of ports when they "only" have a given number of connections at the
application level. When this happens, the impact is that only their new
connection cannot be opened, the old ones do not get killed. I think it
makes sense to apply the same strategy here.

Keep in mind that the alternative for people who don't understand what is
happening will be to start again to open as many connections as they need
streams, and that's clearly not what we want to see!

> I'm not saying implementations can't pick their favorite architecture, but
> whatever they pick, it still has to play by the rules.

Absolutely, provided they understand how their architecture copes with
the rules, which is not commonly the case from what I'm seeing in field.
We're regularly seeing protocols and applications running over TCP where
the *client* is required to close first! Seeing this is a proof of a
misunderstanding of the underlying protocols, and we can't always blame
users for that, at least we should educate them.

> The protocol
> shouldn't be modified to make it easier for people who choose the option of
> writing random bytes.

That's irrelevant to what we're discussing about.

Willy

Received on Monday, 24 November 2014 17:11:03 UTC