Node-postgres: Do i need to finish the pool with pool.end() method?

Created on 14 Oct 2017  路  3Comments  路  Source: brianc/node-postgres

Hi Brian C.

First of all thank you for your hard work to implement this library dealing with PostgreSQL.

  • question please, i have an application bonded with Postgres database using pooling approach.
    Do i need pool.end() to finish the pool and it's internal timer(s) ??
    Because there is time(s) inside the pool from what i read in your documentation, i'm thinking for long period timer(s) overflow.
    I've read also that the garbage collector will cure memory leak so it can be forever BUT not sure about it.
    Does that make scene to you or I've got wrong idea about it ??

Looking forward for your kind answer.

Example of my database Class

const { Pool } = require('pg');
class database{    
    constructor(){
        if(this.instance){
            throw new Error("You can't instatiate new instance of database class instead use 'getInstance' method");
        }
        this.pool;
    }
    connect(host=null, user=null, password=null, dbName=null, port=null){
        var config = require('./config.json');
        this.pool = new Pool({
            user: user || config.db.username,
            host: host || config.db.host,
            database: dbName || config.db.databaseName,
            password: password || config.db.password,
            port: port || config.db.port || 5432,
            client_encoding: config.db.encoding || 'utf8'
          });
        config = null;
        // the pool with emit an error on behalf of any idle clients
        // it contains if a backend error or network partition happens
        this.pool.on('error', (err) => {
            console.error('Unexpected error on idle client "DATABASE" class: ', err);
            process.exit(-1);
        });
        this.instance = new database();
        return;
    }
    getAllTables(){
        return this.query("SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'public'");
    }
    query($sql){
        var newPromise = new Promise( (resolve, reject)=>{
            this.pool.connect().then(client=>{
                return client.query($sql).then(data =>{
                    client.release();                    
                    resolve( {fetch: data.rows , rowCount:data.rowCount} );
                }).catch(err=>{
                    client.release();
                    reject(err);
                });
            }).catch(err=>{
                reject(err);
            })
        });
        return newPromise;
    }
};

module.exports = new database();
question

Most helpful comment

Short version - NO. An app that keeps creating and releasing the pool won't scale well.

All 3 comments

Short version - NO. An app that keeps creating and releasing the pool won't scale well.

You can use pool.end() to close any remaining clients if you鈥檙e done with the pool, but in typical use that won鈥檛 be until the application itself exits. (The point of a pool during its lifetime is to keep clients alive.) Garbage collection is not really involved here.

Aside: please take a look at https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern and pool.query.

'use strict';

const { Pool } = require('pg');
const config = require('./config.json');

class Database {
    connect(host, user, password, dbName, port) {
        this.pool = new Pool({
            user: user || config.db.username,
            host: host || config.db.host,
            database: dbName || config.db.databaseName,
            password: password || config.db.password,
            port: port || config.db.port || 5432,
            client_encoding: config.db.encoding || 'utf8'
        });

        // the pool with emit an error on behalf of any idle clients
        // it contains if a backend error or network partition happens
        this.pool.on('error', (err) => {
            console.error('Unexpected error on idle client "DATABASE" class: ', err);
            process.exit(-1);
        });
    }

    getAllTables() {
        return this.query("SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'public'");
    }

    query(...args) {
        return this.pool.query(...args);
    }
}

module.exports = new Database();

Thanks @charmander .
I know that the query itself will return me back a promise. but in this case i should use client.release() method when i use the resolved in another place.
And because i want very clean promise in my higher level of my code i wrapped it with new promise just to add this (pool release) after i get the response.
Does it effect on the preference?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

frmoded picture frmoded  路  3Comments

gajus picture gajus  路  4Comments

spollack picture spollack  路  4Comments

wrod7 picture wrod7  路  4Comments

chrisjensen picture chrisjensen  路  4Comments