On Mon, Nov 02, 2026 at 01:40:19PM -0800, Dustin Lundquist wrote:
> A connection attached with attach-srv is removed from the stopping list
> when it is reversed, and the soft-stop GOAWAY is only sent on frontend
> connections, so a stopping process never tells a reverse HTTP peer to
> leave. The connection is not a job either, so the process keeps it open
> until its last client stream ends. The peer sees no reason to redial,
> while the new process has no connection to it: requests to that server
> get a 503 for as long as the old process lingers, which with
> long-running requests and no hard-stop-after can be minutes.
> Once the backends are stopped in do_soft_stop_now(), release the idle
> connections of every rhttp server, and refuse a reversed connection
> back into the idle list of a stopped backend, so one still carrying
> streams is closed as soon as its last stream ends. Each closure prompts
> the peer to redial into the new process. Gating on the stopped backend
> rather than on "stopping" keeps reverse connections usable during a
> "grace" period, while this process still serves.
> This only helps connections that are idle at the reload. One that
> carries a stream is still kept until its streams end, and the peer is
> not told to replace it meanwhile, so a pool whose connections are all
> busy is not improved. That needs a GOAWAY on busy reverse connections.
> Measured with pool-purge-delay 3600s and one 8s or 20s request in
> flight across a reload: requests to the server are served again after
> the peer's reconnect delay (1.1-1.2s for a peer with a 1.0-1.5s
> backoff, 0.44-0.56s for one that redials after 0.5s), against the
> whole remaining life of the in-flight request without this patch. The
> in-flight request still completes. With 16 concurrent requests over 4
> connections, nothing is idle and the result is unchanged.
> This partially addresses GitHub issue #3556.

Thanks for your report. It's still good to see some interest in reverse
HTTP. At first glance, I am mostly okay with your patch. You mentionned
the GOAWAY emission as a possibility, but I think there is no real
interest from an HTTP/2 client point of view, so closing the connection
using srv_cleanup_connections() seems the correct approach.

In fact, I wonder if your patch should be generalized to all backends,
regardless of reverse HTTP usage. Idle connections are already cleaned
up when a server is put in maintenance mode, and srv_add_to_idle_list()
already has a condition to reject idle connections in this case. A
disabled backend is quite similar to a server in maintenance. Of course,
the main benefit would still be for reverse HTTP case, but even in
normal case it could be useful to release connections faster on legacy
worker processes. I have to perform some tests and I'll let you know my
observations.

-- 
Amaury Denoyelle


Reply via email to