Repository navigation
Conversation
psycopg answers Ctrl-C by cancelling the query and then reading the server's reply. A second Ctrl-C during that cleanup, easy over an SSH tunnel where it takes a round trip or two, cut it short: the cancel could be lost, the query kept running on the server and every later statement failed with "another command is already in progress". After a cancelled query pgcli now checks the connection. If it is still busy it cancels again and reads the reply (psycopg.pq only, at most 5s). If the server does not answer, or yet another Ctrl-C lands, it cancels (at most 2s) and closes the connection, and the next statement reconnects through the usual closed-connection path. Four tests, all failing without the change; one also fails if the last-resort path only closes the connection.
DiegoDAF
added a commit
to DiegoDAF/pgcli.daf
that referenced
this pull request
Oct 16, 2026
When the user interrupts the recovery itself, pgcli cancels the query and closes the connection. A further Ctrl-C during that cancel skipped it, so with four quick Ctrl-C over a tunnel the query kept running on the server after the session gave up on it. Ctrl-C is now ignored for the at most 2 seconds the cancel takes (main thread only; elsewhere signal handlers cannot change). The new test fails without the change.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Pressing Ctrl-C twice on a long query can leave the connection unusable: every later statement,
rollbackincluded, fails withand the query keeps running on the server. We hit it over an SSH tunnel to a remote server, but a tunnel is not required, just enough round-trip time.
psycopg's
Connection.wait()answers the first Ctrl-C by sending a cancel and then reading the server's reply. A second Ctrl-C during that cleanup interrupts it: the cancel may never go out and the reply is never read.execute_command()then prints "cancelled query" without looking at the connection.After a cancelled query, pgcli now checks whether the connection is still busy. If it is, it cancels again and reads the pending reply, using
psycopg.pqonly and waiting at most 5 seconds. If the server does not answer, or yet another Ctrl-C arrives, it cancels (at most 2 seconds, ignoring Ctrl-C meanwhile so the query does not outlive the session) and closes the connection, so the next statement goes through the existing reconnect path. A connection that is not busy is left alone, so session state survives an ordinary Ctrl-C.Reproduced end to end by driving pgcli with pexpect through a TCP proxy that adds 150 ms each way: two Ctrl-C 0.15 s or 0.4 s apart left the connection busy and the
pg_sleeprunning on the server. With this change the next statement works and the sleep is cancelled, also with three, four or six quick Ctrl-C.5 tests against a live server, all failing on main; two of them also fail if the last-resort path only closes the connection, or lets a Ctrl-C skip its cancel.
The cleanup gap itself is in psycopg, reported as psycopg/psycopg#1444. A fix there would leave the connection closed instead of busy; this change is still needed to cancel the query and keep the session when the connection can be recovered.
Checklist
changelog.rst.AUTHORSfile (or it is already there).pip install pre-commit && pre-commit install).On the third box:
.pre-commit-config.yamlpins an olderruff-pre-committhan the onetox -e styleinstalls, and the two disagree on formatting, so I ranruff checkandruff formatmatching the CI instead, both clean.