Repository navigation
fix(test): ignore an ended revision fixture pool's session error the database drop causes - #3547
Conversation
…database drop causes pg-pool's end() resolves before its idle sessions close. Since lane database drops go over a direct connection (#3536), the drop can reach the server before a closing backend reads its Terminate message; the server's 57P01 then reaches the pool's idle listener, which re-emits it on the pool, and with no listener that failed the test in teardown (finding 2379).
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs maintainer review before merge. What this changesThis PR handles late pool errors during revision-fixture disposal and adds a regression case for SQLSTATE 57P01. Example: A forced test-database drop terminates an idle session after pool.end() resolves.
Review scores
ProductKind: Test only · Worth it: Yes · Fix scope: Complete Merge readiness✅ Ready for maintainer review Keep this PR open: it provides a focused repair for intermittent PostgreSQL fixture teardown failures, and no actionable patch defect was found. Priority: P2 Before mergeNone. FindingsNone. Tests
Agent review detailsHow this fits togetherRevision-worker integration tests use this shared fixture to create isolated PostgreSQL databases, stop workers, close connection pools, and drop their databases. flowchart TD
A[Revision worker test] --> B[Shared database fixture]
B --> C[Stop owned workers]
C --> D[Attach disposal listener]
D --> E[End fixture pools]
E --> F[Force drop database]
F --> G[Late session error]
G --> D
Technical reviewBest possible solution: Keep the repair in the shared revision fixture, preserving active-test error visibility and bounded teardown failures. Do we have a high-confidence way to reproduce the issue? Source inspection confirms that pg-pool can forward an idle-client error after pool closure begins, while main's fixture has no listener; the author reports a real PostgreSQL before-and-after reproduction, which was not rerun. Is this the best way to solve the issue? The listener is a small repair in the existing shared owner, installed only during disposal without changing production pool behavior or weakening timeout assertions. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 4c945e93b112. Provenance checked
TestingProof path: in-process harness. SecurityNone. EvidenceWhat I checked:
Likely related people:
LabelsLabel changes:
Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment Reviewed October 24, 2026, 8:12 PM ET / October 25, 2026, 00:12 UTC. |
Problem
PostgreSQL Application started failing intermittently after #3536, with a revision test dying on
terminating connection due to administrator command(SQLSTATE 57P01):postgres-worker-agent-revision-stop.test.mjs, "Agent deletion finalization rejects an expired lease without removing state".postgres-worker-agent-revision-yielded-redeploy.test.mjs, "a yielded redeploy overtaken by an Agent stop finishes its predecessor stop before it ends stopped".The revision fixture's teardown ends its pools and then drops the test's database
WITH (FORCE). pg-pool'send()resolves once its idle clients are removed, before their sessions close:client.end()only sends Terminate. Since #3536 the drop goes over a direct connection, which takes milliseconds rather than the 0.2-0.4 s adocker compose exec psqltook. So the drop can now reach the server before a closing backend has read its Terminate. That backend then sends FATAL 57P01 to its client. pg-pool's idle listener, which_remove()leaves attached, re-emits the error on the pool. The fixture pools have noerrorlistener, so the emit throws and the test fails in its teardown. The failing test's duration matches its passing neighbours on #3536 heads, because test durations include the per-test copy and drop.Change
tests/helpers/postgres-worker-revision-fixture.mjs: teardown adds a no-operrorlistener to each fixture pool before ending it. That covers pools a worker's stop or the test already ended. Errors from a pool are still raised while its test runs; only an ended pool's session closing during the drop is ignored.postgres-worker-agent-revision-health.test.mjs: a new case releases an idle client, disposes the fixture, and then delivers the 57P01 that client would receive from the drop. It asserts nothing throws. The leaked-client case is unchanged: a checked-out client has no idle listener.Verification
pool.end(), directDROP DATABASE ... WITH (FORCE). Without the listener, 5 of 320 rounds raised an uncaught 57P01. With it, 0 of 320.oce-ci-lane) passes with the change.Got unwanted exception ... terminating connection due to administrator command.Risks