-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Calling .end
on a client (or pool) does not wait for connections to close
#3287
Comments
Yes, please add a callback to The issue manifested itself like this for me: I use this package to verify DB writes in E2E tests, and Jest had this error:
Running Jest with
My code for reference
|
@opyate the |
Ah, of course, I missed Here's my solution for anyone else landing here.File setupFilesAfterEnv.ts:
And my helper becomes:
|
the problem is with pool.end() client.end works as you'd expect, at least when you don't provide a callback. pool.end() returns immediately, before the connections are truly closed. I am assuming the reason most people wound up on this thread is because of their jest tests throwing an "open handle" error. To wait till all the connections in a pool are truly closed you can wait for all clients in the pool to end(). Whenever I have to wait till all the connections are truly closed, I use this helper function in my database class: async closeAndWait(){
// @ts-ignore
const clients = this.pool._clients as Client[];
await Promise.all(clients.map(client => client.end()));
} or if you don't want to end the clients yourself: async closeAndWait(){
// @ts-ignore
const clients = this.pool._clients as Client[];
const endPromises = Promise.all(
clients.map(client => new Promise<void>(resolve => {
client.once("end", resolve);
})
)
);
this.pool.end();
await endPromises;
} And then on test files: afterAll(async () => {
await db.closeAndWait();
}); I am not sure why pool.end is working for @opyate but I am assuming it's something to do with how inidividual clients work in pg-pool vs running pool.query. |
The reason |
@charmander I did a little more digging. It appears to be working for opayate because he's presumably calling client.release() which then ends the connection instantly, so when he calls pool.end(), there are no connections to close. I think the Pool class should have a endAndWait function like the one I mentioned earlier. Should I submit a pull request? |
I’d think |
Hi there, it seems that there is a bug around
client.end
/pool.end
in that when awaited (or using callbacks) the promise can resolve before the underlying connection / stream has disconnected.Digging through the code a bit, it seems like the issue is in this bit of code:
node-postgres/packages/pg/lib/connection.js
Lines 189 to 199 in 54eb0fa
I think here we should hook into the callback from the sockets end event: https://nodejs.org/api/net.html#socketenddata-encoding-callback and ensure that the original promise does not resolve (or callback fire) before observing this.
The text was updated successfully, but these errors were encountered: