node-postgres icon indicating copy to clipboard operation
node-postgres copied to clipboard

pool.connect() waits forever

Open joker-8989 opened this issue 4 years ago • 11 comments

When listing the node versions, I noticed that I was forever waiting for pool.connect() to process.

import {Client, Pool} from "pg";
import * as fs from "fs";
import * as process from "process";

export interface DatabaseInterface {
    connect(): Promise<void>;

    end(): Promise<void>;

    getClient(): Promise<Client>;
}

export class Db implements DatabaseInterface {
    private client: Client;
    private pool: Pool;

    constructor() {
        const env = process.env["ENV"] || process.env.NODE_ENV || "dev";
        console.log(`DETECT ENV:: ${env}`);

        const config = JSON.parse(
            fs.readFileSync("./config/database.json", "utf-8")
        )[env];

        console.log(config)

        this.pool = new Pool(config);
    }

    async getClient(): Promise<Client> {
        return this.client;
    }

    async connect(): Promise<void> {
        this.client = await this.pool.connect();
    }

    async end(): Promise<void> {
        this.client.release();
        await this.pool.end();
    }

}

My environment is as follows. Just in case, I tried to match the pg version to 7.3.3, but the result did not change.

# Before update
Node: v8.12.0
pg: 7.3.0
# After update
Node: v12.18.3
pg: 8.3.3

The contents of console.log (config) are as follows I'm using Postgres 11.8 on AWS but I don't think it's a network issue as I can do the DB connection itself.

{
    "driver": "pg",
    "host": "xxxxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com",
    "database": "testdb",
    "user": "test",
    "password": "test1234",
    "port": 5432
  }

joker-8989 avatar Sep 09 '20 04:09 joker-8989

Did you end up solving this? I'm facing a similar issue with RDS + node-postgres.

bradleybonitatibus avatar Sep 25 '20 13:09 bradleybonitatibus

I don't know if it's the same issue but I just ran into this today with pg version 7.12.1:

  • pg version 7.12.1 with nodejs version 14.13.1 just hangs forever
  • pg version 7.12.1 with nodejs version 12.19.0 works fine, connects immediately

Nothing else is different -- I can downgrade/upgrade nodejs and restart my app to resolve/reproduce this issue.

However, after I upgraded to pg version 8.4.1, it's working with both node 12.19.0 and 14.13.1:

  • pg version 8.4.1 with nodejs version 14.13.1 works fine, connects immediately
  • pg version 8.4.1 with nodejs version 12.19.0 works fine, connects immediately

This is all on Ubuntu 20.04 LTS.

jbuhacoff avatar Oct 11 '20 22:10 jbuhacoff

Yeah pg<=8.0 is not compatible with node>=14

brianc avatar Oct 12 '20 15:10 brianc

Just bump your version to "pg": "^8.5.1" (or latest) to fix the issue.

dotspencer avatar Jan 26 '21 23:01 dotspencer

I am still having the same issue "pg": "^8.5.1" and node v14.15.4 with postgres version 13

nabeelparkardarwin avatar Mar 17 '21 10:03 nabeelparkardarwin

I have the same issue with [email protected] and a Node.js 14.x environment on AWS Lambda connecting to postgres 11:

const { Client } = require('pg');

exports.handler = async(event, context) => {
    context.callbackWaitsForEmptyEventLoop = true;
    try {
        console.log(`Nodejs ${process.version}`)
        
        const client = new Client({
            connectionTimeoutMillis: 500
        });
        
        console.log("connecting...");
        await client.connect();
        console.log("connected");

        const res = await client.query('SELECT NOW() as result');
        console.log(res.rows[0].result);
        
        await client.end();
        console.log("done");
    }
    catch (e) {
        console.log(e);
    }

    return {statusCode: 200, body: "ok"};
};

Results in

START RequestId: xxxxxxxxxxxxxxx Version: $LATEST
2021-06-03T09:10:11.880Z	xxxxxxxxxxxxxxx	INFO	Nodejs v14.16.1
2021-06-03T09:10:11.881Z	xxxxxxxxxxxxxxx	INFO	connecting...
2021-06-03T09:10:12.403Z	xxxxxxxxxxxxxxx	INFO	Error: timeout expired
    at Timeout._onTimeout (/opt/nodejs/node_modules/pg/lib/client.js:92:26)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)
END RequestId: xxxxxxxxxxxxxxx
REPORT RequestId: xxxxxxxxxxxxxxx	Duration: 575.34 ms	Billed Duration: 576 ms	Memory Size: 128 MB	Max Memory Used: 70 MB	Init Duration: 206.97 ms

Executing the exact same code with a Node.js 12.x environment works just fine:

START RequestId: xxxxxxxxxxxxxxx Version: $LATEST
2021-06-03T09:14:19.542Z	xxxxxxxxxxxxxxx	INFO	Nodejs v12.22.1
2021-06-03T09:14:19.549Z	xxxxxxxxxxxxxxx	INFO	connecting...
2021-06-03T09:14:19.646Z	xxxxxxxxxxxxxxx	INFO	connected
2021-06-03T09:14:19.684Z	xxxxxxxxxxxxxxx	INFO	2021-06-03T09:14:19.664Z
2021-06-03T09:14:19.725Z	xxxxxxxxxxxxxxx	INFO	done
END RequestId: xxxxxxxxxxxxxxx
REPORT RequestId: xxxxxxxxxxxxxxx	Duration: 218.93 ms	Billed Duration: 219 ms	Memory Size: 128 MB	Max Memory Used: 70 MB	Init Duration: 183.81 ms

Everything works fine on a local machine with Node.js 14.x so there must be something special about the AWS lambda environment.

henrythasler avatar Jun 03 '21 09:06 henrythasler

@henriksjostrom If you're on the latest version and the connection is timing out on AWS then it's probably a firewall / security group issue.

Also, you do not need callbackWaitsForEmptyEventLoop = true with the Promise based API and you should be ending the connection in a finally { ... } block to ensure that it's closed if there's an error in the query execution.

sehrope avatar Jun 03 '21 10:06 sehrope

I fail to see the connection between the runtime version (12 vs 14) and security groups. Besides that, the lambda in my example has an All/All/0.0.0.0/0 security group attached. The code is a minimal example I came up with to show at least an error message. If I leave out the connectionTimeoutMillis: 500 it just fails silently after a few milliseconds (according to the manual connect() should not timeout on it's own).

henrythasler avatar Jun 03 '21 10:06 henrythasler

anyone able to fix this? or any suggestions.

suryaiiit avatar Aug 03 '21 04:08 suryaiiit

I had the problem with "pg": "^8.6.0", "pg-pool": "^1.6.0", node14 and pg11

Updating pg-pool to 3.4.1 fixed the issue

KoalaMoala avatar Jan 07 '22 17:01 KoalaMoala

Hi, So i have chased this issue for a day now solid...

AWS SAM node@14 Postgres (10,12,14) pg 8.7.1

Not specifically Pool, both Pool and Client expiring.

Now i am using this through an MVC stack built for lambda (cerberus-mvc) and the issue i get with pg timing out on the pg middleware (which loads it from service) is actually due to where we require pg in the system.

If i run node 14 on SAM i can only const pg = require('pg') from the handler file and pass it in to the stack.... if i try to load it in the middleware which is a file further down the trace, it loads fine but i get timeouts. Load it in the controller and its fine.

My initial thought was that is was due to an async/await/promise issue, but its not. It is purely where we load the dependency. Doesn't matter what options you send in to pg when using, doesn't matter what version of db you connect to, works totally fine on node 10 and 12 but pg connections timeout on 14 if the require('pg') is anywhere but the handler or the controller.

Clearly this is going to be a loading issue on the dep, somethings not ready somehow, but its only specific to node 14 on AWS SAM (maybe online in lambda too). I am hoping a pg or node up version will solve this, i will continue to use node 12 until 16 is out now (14 broke a lot i hear).

So this is here to help me when i come looking again or if anyone else has this issue, try moving the dep require to the root file handler if your lambdas are more complicated than a single script.

smiffy6969 avatar Jan 18 '22 09:01 smiffy6969