fix(postgres): retry transient Accept errors in the data-plane loop instead of exiting - #57
Conversation
…nstead of exiting PostgresServer.acceptLoop had the identical unconditional-exit-on-any- Accept-error bug that PR #56 fixed in Demux.acceptLoop, and was intentionally left out of that PR's scope. This is the sibling fix: acceptLoop now mirrors Demux.acceptLoop (and, in turn, net/http.Server.Serve) by retrying any non-shutdown Accept error with a capped exponential backoff (reusing demux.go's demuxAcceptRetryBaseDelay/demuxAcceptRetryMaxDelay constants so the two loops can't drift), logging at WARN, and only exiting cleanly on an intentional Stop/Shutdown.
|
Claude finished @andybons's task in 1m 36s —— View job Code Review
Summary: This is a clean, correct fix. Verified:
No bugs, race conditions, or security issues found. I was unable to execute |
What
Sibling of #56.
PostgresServer.acceptLoopexited permanently on anyAccept()error — a transient one (EMFILE/ENFILEunder fd exhaustion,ECONNABORTED; realistic for a DB proxy holding many long-lived relay connections) would kill the Postgres listener until process restart.Now it mirrors
Demux.acceptLoop(andnet/http.Server.Serve) exactly: clean exit only on our own shutdown (s.closed); otherwise capped exponential backoff (5ms→1s), WARN, and retry, with the backoff reset after a successful accept. It reuses the samedemuxAcceptRetryBaseDelay/demuxAcceptRetryMaxDelayconstants (same package) so the two loops stay identical. Like the demux fix, it doesn't gate on the deprecatednet.Error.Temporary().This was the out-of-scope note on #56 — its blast radius was unchanged by that PR, so it's fixed here separately.
Tests
Test-first, mirroring the demux tests (and reusing the
scriptedAcceptListenerhelper): a listener that fails 3× with a simulatedEMFILEthen hands out a real conn — proves the loop retries and the conn is handled (SSLRequest →S); plus a clean-exit-on-Stop()test. Both mutation-checked (revert retry → red; remove shutdown check → spin-red).go test -race ./..., vet, gofmt clean.CHANGELOG
v0.19.1.