-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
client.end() never resolves in Deno when using SSL connections #3420
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
Comments
It doesn’t sound like there’s anything for pg to do, then. I don’t think it’s appropriate to add specific checks to pg to implement incorrect/inconsistent fallback behavior for an unsupported runtime’s compatibility layer, especially considering there are user-side workarounds like not (You should use |
Sadly, I think it is unavoidable because of leaky abstractions. Breaking changes and new APIs are a thing, even between two major LTS versions of NodeJS. Sometime, libraries have to work around their language/runtime quirks to endure. At the end, the maintainer decide what is going to be the scope of the project he's maintaining, I totally get that. 👍
IMO, not awaiting a promise is not a super good solution in its own because it could cause race conditions. Also, I personnally configure test runners to detect open handles when a unit test/integration test ends and this would definitely trigger them. Do you think there is a way for me to check if the client's connection is correctly closed from the Here is an example of what I mean: await new Promise((resolve) => {
client.end();
let intervalId = setInterval(() => {
if (!client.isConnectionClosed) return;
clearInterval(intervalId);
resolve();
}, 10);
}); This scenario would be more acceptable for me:
Good to know, thank you for the advice! |
In general, yes, but
It doesn’t look like your proposed library patch would affect that, since it emits I haven’t investigated too deeply yet, but it looks like Deno might emit the const {connection} = client;
connection.stream.on('end', () => {
connection.emit('end');
}); (in |
Thank you, your solution worked and no open handles is detected by the system. 🥳 If I may add a little feedback: currently, the type of For people looking to fix the same problem, here's how you can fix it: import pg from "pg";
async function endClientConnection(client: PgClient) {
if (client.ssl) {
// @ts-expect-error: connection is not exposed by `pg` type definitions
const ( connection } = client;
connection.stream.on('end', () => {
connection.emit('end');
});
}
await client.end();
} For people which have the same problem using Slonik with Deno, you will have to implement your own PG driver factory: Edit: update example to use |
It’s not a private or hidden property; the TypeScript typings for pg just aren’t complete (and are not currently part of this repo). So feel free to send PRs to DefinitelyTyped as necessary. |
I wanted to say thanks for sunch a comprehensive issue report as this w/ an enormous amount of investigation & thought before opening it. It's a rare treat to read something like that. Sorry for not seeing it sooner. I'm trying to do a new thing where I keep my github streak going as much as possible so should hopefully be more engaged. I'm not sure anything needs to be done now as it looks like a solution was met but, thanks anyway! |
Hello there,
First of all, thank you for your work on
pg
, I used it extensively and it's a great library!I am currently working on a project with Deno 2,
pg
, and a database hosted on Neon Postgres.I ran into a weird issue when calling
await client.end()
:This error only happens when connecting to a database using the
sslmode=require
option.I had no trouble working on the project with a local Postgres instance.
Neon Postgres only supports SSL connections so this problem is kind of blocking for me.
How to reproduce
I created a repository with minimal code to reproduce the error: https://github.com/SylvainMarty/pg-deno-ssl-issue.
You can also copy-paste the following code in a Deno 2 project:
Investigation
Since I was curious, I dug deeper and I realized the error is happening because the event
end
is never emitted by the Connection class declared inconnection.js
:node-postgres/packages/pg/lib/connection.js
Lines 61 to 63 in 477f812
To be sure, I added a log in the
end()
method of theconnection.js
file:And ran the code again, this time with the log enabled:
In deed, the
close
event listener is never called because it doesn't exist.Why this happens
This problem is due to the fact that Deno's compatibility layer with the Node.js TLS API is not 100% complete yet.
I found the following test suites which are still in the TODO file of the Node compat project:
parallel/test-tls-close-error.js
parallel/test-tls-close-event-after-write.js
parallel/test-tls-close-notify.js
You've read it right, the
close
event is not emitted like in NodeJS.I have tried to make those tests pass in Deno/Node compatibility project but without success. There's actually a lot of work to be done on Deno's side for even being able to run those tests correctly, even before actually fixing the issue at hand (Deno doesn't support self signed certificates and that's how NodeJS expects those tests to be running).
I am planning to open an issue on Deno's repo and see if I can help advance on this subject but from what I've seen, the issue is linked to multiple problems and this might not be fixed anytime soon.
Moving forward
Yes I know, everything points to this being more of a Deno scope than
pg
's.Now, I think
pg
can be updated to work around this issue.Actually, the workaround I found was as simple as this change in
pg/lib/connection.js
:I've tested this workaround against the minimal reproducible example provided above, and it successfully resolves the issue. The client.end() call completes properly when using SSL connections to Neon Postgres from Deno.
I'm offering this as a tentative solution and am open to alternative approaches if you have concerns about this implementation.
I saw your comment on the issue #2225 and I understand supporting new runtimes is not a priority for you. My primary goal is to enable Deno users to work with
pg
and Neon (or other SSL-required Postgres instances) without hitting this blocking issue.Since
pg
is a building block for many libraries used extensively by the JS ecosystem (to quote a few: TypeORM, Slonik, pg-boss), I really think it would be great for everyone if this library worked well with Deno 2.I personally had no trouble working with the
pg
library on Deno until I found this issue (my project has extensive integration tests andpg
is doing a great job at everything we throw at it).The text was updated successfully, but these errors were encountered: