brianc / node-postgres

PostgreSQL client for node.js.
https://node-postgres.com
MIT License
12.22k stars 1.22k forks source link

Client#query promise stuck when connection closed #1500

Closed rkaw92 closed 6 years ago

rkaw92 commented 6 years ago

Hi, we've just encountered a problem which seems to predictably occur when a Client instance disconnects. It results in promises returned from Client#query never settling as fulfilled nor rejected (when using callbacks, those are not fired, either).

The below gist is a trivial example (with output) to reproduce the behavior. If you cut off the connection to PostgreSQL at some point (in my case, it's a Docker container with postgres:9.6 being stopped), the next .query() call rejects with an error, but the next call after that never settles its promise, as illustrated by the output.

https://gist.github.com/rkaw92/9cbd71fdb98d74f01c624bb2a003cd2a

You'll notice that subsequent queries are never executed, and they never reject, either - they just hang.

The issue has several important consequences:

I think I've pinned down this behavior to the following sequence of events (hold on, it's going to be a bumpy ride over client.js):

Trying to think of a solution right now. Perhaps having a "dead" flag that rejects all subsequent query calls would do. One other thing I can think of would be resetting readyForQuery every time we get a connection error, but it does not sound like a wise thing to do.

In any case, unless callbacks/promises returned from Client#query() fire every time eventually, there is a demonstrable hazard of getting hung calls in user apps and exhausted client pools in knex.js.

charmander commented 6 years ago

Duplicate of #1454