Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

node.js - Query timeout in pg-promise

I want to add timeout to pg-promise queries so they will fail after some amount of time if database have not yet responded. Is there any recommended way to do that or should I make custom wrapper that will handle timer and reject promise if it's too late?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

From the author of pg-promise...


pg-promise doesn't support query cancellation, because it is a hack to work-around incorrect database design or bad query execution.

PostgreSQL supports events that should be used when executing time-consuming queries, so instead of waiting, one can set an event listener to be triggered when specific data/view becomes available. See LISTEN/NOTIFY example.

You can extend pg-promise with your own custom query method that will time out with a reject (see example below), but that's again another work-around on top of a design problem.

Example using Bluebird:

const Promise = require('bluebird');

Promise.config({
    cancellation: true
});


const initOptions = {
    promiseLib: Promise,
    extend(obj) {
        obj.queryTimeout = (query, values, delay) => {
            return obj.any(query, values).timeout(delay);
        }
    }
};

const pgp = require('pg-promise')(initOptions);
const db = pgp(/* connection details */);

Then you can use db.queryTimeout(query, values, delay) on every level.

Alternatively, if you are using Bluebird, you can chain .timeout(delay) to any of the existing methods:

db.any(query, values)
    .timeout(500)
    .then(data => {})
    .catch(error => {})

See also:

UPDATE

From version 8.5.3, pg-promise started supporting query timeouts, via property query_timeout within the connection object.

You can either override the defaults:

pgp.pg.defaults.query_timeout = 3000; // timeout every query after 3 seconds

Or specify it within the connection object:

const db = pgp({
    /* all connection details */

    query_timeout: 3000
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...