Skip to content

fix(pg-cursor): clear query_timeout when the cursor finishes - #3808

Open
DylanMerigaud wants to merge 1 commit into
brianc:masterfrom
DylanMerigaud:fix/pg-cursor-query-timeout
Open

DylanMerigaud wants to merge 1 commit into
brianc:masterfrom
DylanMerigaud:fix/pg-cursor-query-timeout

Conversation

@DylanMerigaud

Copy link
Copy Markdown

Fixes #3497

When a client has query_timeout set, Client#query wraps the query's callback so the timer is cleared once the query finishes. pg-cursor never calls callback, so for a cursor the timer always ran to the end. When it fired, it called the callback with Query read timeout even though the cursor had already been read and closed and the client had ended. Until then the timer kept the cursor, its rows and the process alive, which is the retention reported in the issue.

With this change the cursor calls callback once: with its result when it ends, with the error when it fails. pg-query-stream already does the same on its cursor's end and error events. Code that passes no callback sees no difference; a callback passed to client.query(cursor, callback) is now called when the cursor finishes instead of only when the timeout fires.

Testing

  • New packages/pg-cursor/test/query-timeout.js. One test reads and closes a cursor, the other makes it fail with SELECT 1 / 0. Both wait past a 100 ms query_timeout and check that the callback ran exactly once, without a timeout error. Both fail on master with Query read timeout and pass with this change.
  • yarn lint passes.
  • yarn lerna exec --concurrency 1 --ignore pg-native yarn test passes on Node 24.10 against PostgreSQL 17.6 set up like CI (SSL on, the SCRAM test roles). The pg-native suite crashes with SIGSEGV on my machine, on master too, so I left it out; this change does not touch it.

AI assistance

I drafted this with Claude Opus 5.5, read the diff line by line and can answer for every change.

pg-cursor never called the Submittable callback, so the timer that
Client#query starts for query_timeout was never cleared. It fired after
the cursor had finished, called the callback with 'Query read timeout',
and kept the cursor and the process alive until then. Call the callback
once when the cursor ends or errors, as pg-query-stream already does.

Fixes brianc#3497
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.

pg-cursor usage leads to memory leak

1 participant