W dniu 19.12.2025 o 11:55, Willy Tarreau pisze:
On Fri, Dec 19, 2025 at 11:47:10AM +0100, Hank Bowen wrote:
I have some more questions, all of them except the last one (that is the one
after the numbered list) I ask only for double-checking my understanding but
if at any point I take too much of your spare time just let me know.

For the following (hopefully fast-to-respond) questions, could you respond
just "yes" to these on which I'm correct?

1. A session is the entity which is started by a client-initiated TCP
connection,
2. while a session always starts with about the start of such a TCP
connection, in practice assuming that a client connects using SSL, the
session becomes of a practical use only after SSH handshake on a given TCP
connection is done,
3. a single client-initiated TCP connection can contain (or perhaps I should
rather say be related to) only one session (well, being a bit more strict,
as an edge case, if a TCP connection failures very early it can be perhaps
viewed as containing zero sessions),
4. in order to be sure that in case of the server closing connection the
browser will be able to silently retry it, we only need to care about the
proper handling of the first request as the subsequent requests are already
guaranteed to be handle properly as a premature server close is a normal
thing and clients are expected to retry such requests,

Yes to all these.

5. when it comes to the question why the first request is different in the
regard described above - theoretically clients can retry also this request
and some of them do.

Yes.

However, some of them do not and the rationale for such
a design choice is that under normal circumstances (meaning direct client
<-> origin server connection) the connection to which the first request was
dispatched will not expire (or at least it's extremely unlikely) due to
keep-alive related timers as keep-alive is not even being used here yet.

At first I had issues parsing this one but I think you mean that we
consider that a connection will not quickly expire while waiting for its
first request. If so, that's indeed the point.

Yes, that is exactly what I meant.

The common issue with
keep-alive (and most annoying case) is servers responding that they do
intend to keep the connection alive and immediately close after the
response. If they do it in the same packet we get the info, if they
don't, we get this info late, often after having sent a new request
there. But indeed, servers will generally close much faster after a
first request than before since it's unsure whether the client wants
to reuse that connection.

I'm not sure if I properly understand the last sentence. That is, it should be understood: "during the first request the issue of reusing connection is of no matter at all because it was not even completely used yet, so the possible timeout will be typically high; but when it comes to subsequent requests the server cannot be sure if a client having received a complete responses to all the requests it initiated on this TCP connection will want to send yet another request on it, so the timeout will typically be low (in order to prevent server resources being taken unnecessarily)"?

However, I'd have a separate question concerning that you said about
criteria by which a connection is considered idle:

"once both a request and response have been fully exchanged, by definition
the connection is idle again and reusable for a new request/response
exchange"

OK, but in the description of http-reuse "safe" we read:

"There is also a special handling for the connections using protocols
subject to Head-of-line blocking (backend with h2 or fcgi). In this case,
when at least one stream is processed, the used connection is reserved to
handle streams of the same session. When no more streams are processed, the
connection is released and can be reused"

So I don't exactly understand that. Because it seems to me that when a
request and response have been fully exchanged in the given TCP connection,
no streams (no HTTP/2 streams) are already processed in it. Where is the
flaw in my reasoning?

In these multiplexed protocols, there can be more than one request in
flight over a connection, they come in any order. So the principle
remains (and can be generalized to) : "when all requests have been sent
entirely and got their entire response, the connection is idle". For
HTTP/1, it's one req/resp at a time. For H2/H3/FCGI, it can be many at
a time.

OK but the quoted fragment suggests that it is possible to have a single TCP haproxy <-> server connection with streams (in case of HTTP/2 - HTTP/2 streams as I understand) of different sessions (although it would require at least "aggressive" mode of http-reuse). But having considered that the connection is recognized idle only after all requests have been sent and got their entire responses, I cannot see any possibility for that. That is, let us assume that on a given TCP haproxy <-> server connection one stream is being processed and http-reuse is in "aggressive" or "always" mode, so the mentioned TCP connection is not (per documentation) reserved to handle streams of the same sessions. Another client comes in with a request and as I understand the fact mentioned after last comma is a necessary condition for that request being allowed to be directed to that TCP connection. But... there is a stream being processed there, so request - response are not fully exchanged, so the stream cannot be considered idle, so that is anyway impossible. So effectively any TCP connection is anyway reserved to handle streams of the same session. Is there some flaw in my reasoning?

Perhaps it'll be of some help here if I say that I have a pretty good understanding of HTTP/2 protocol (I do understand that requests and responses are broken into frames and frames of different requests can be sent interleaved on the same TCP connection and the same holds true for different responses).


Reply via email to