Skip to content

Drop client queries abandoned during maintenance mode#1244

Open
crodas wants to merge 2 commits into
pgdogdev:mainfrom
crodas:fix-maintenance-mode-disconnect
Open

Drop client queries abandoned during maintenance mode#1244
crodas wants to merge 2 commits into
pgdogdev:mainfrom
crodas:fix-maintenance-mode-disconnect

Conversation

@crodas

@crodas crodas commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Attempt to fix #1242

Maintenance mode parked a fully-buffered request on a bare await that ignored the client socket. If the client gave up and disconnected while the database was paused, its query was still dispatched to the backend once maintenance lifted, running work for a client that was already gone.

Wait for maintenance to lift while watching the client socket, so a disconnect aborts the request before it reaches the query engine. Add a cancel-safe MessageBuffer::read_more that detects the disconnect without consuming any pipelined data, and cover the behavior with an integration test that asserts a write from a disconnected client never lands.

Maintenance mode parked a fully-buffered request on a bare await that ignored
the client socket. If the client gave up and disconnected while the database
was paused, its query was still dispatched to the backend once maintenance
lifted, running work for a client that was already gone.

Wait for maintenance to lift while watching the client socket, so a disconnect
aborts the request before it reaches the query engine. Add a cancel-safe
MessageBuffer::read_more that detects the disconnect without consuming any
pipelined data, and cover the behavior with an integration test that asserts a
write from a disconnected client never lands.
@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 16.66667% with 20 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pgdog/src/net/messages/buffer.rs 0.00% 12 Missing ⚠️
pgdog/src/frontend/client/mod.rs 33.33% 8 Missing ⚠️

📢 Thoughts on this report? Let us know!

@levkk

levkk commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

I think a simpler solution could just be to put the maintenance check at the top of async fn buffer, wdyt?

The disconnect fix for maintenance mode added a separate
wait_for_maintenance method, a small result enum, and matching branches
in the client run loop. buffer() already owns the client socket and
already turns an EOF into a disconnect, so it is the natural home for the
wait and the extra scaffolding is redundant.

Fold the gate into buffer(): once a request is fully buffered, park on
the maintenance waiter while watching the socket, and on a disconnect
clear the request and return the existing abrupt-disconnect event. This
removes wait_for_maintenance, its result enum, and the run-loop plumbing.

The check goes at the bottom of buffer, after the read loop, not at the
top. A client sits idle inside buffer's read loop between requests; if
maintenance turns on while it is parked there, a top-of-function check
has already run and would let the next query through. Gating right before
the buffered request is returned keeps the hold-at-dispatch behavior and
is exercised by the existing idle-client maintenance test.

The gate no longer sets the frontend Waiting state during a park, because
buffer cannot borrow the query engine: the run loop already holds it to
read the backend. A parked client keeps its prior state in SHOW CLIENTS,
an accepted trade for the simpler shape.
@crodas

crodas commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

I think 21764a1 is simpler


#[tokio::test]
#[serial]
async fn test_maintenance_mode_drops_disconnected_client_query() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test succeeds on main without fix.

I think it's because the client.execute will execute parse/describe/sync first and this blocked by maintenance before next execution round-trip anyway. So, try simple_query I guess

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Query engine] maintenance mode should not allow queries from disconnected clients

3 participants