【发布时间】:2018-02-19 23:01:51
【问题描述】:
我想为 pg-promise 查询添加超时,这样如果数据库还没有响应,它们会在一段时间后失败。 是否有任何推荐的方法来做到这一点,或者我应该制作自定义包装器来处理计时器并在为时已晚时拒绝承诺?
【问题讨论】:
标签: node.js postgresql pg-promise
我想为 pg-promise 查询添加超时,这样如果数据库还没有响应,它们会在一段时间后失败。 是否有任何推荐的方法来做到这一点,或者我应该制作自定义包装器来处理计时器并在为时已晚时拒绝承诺?
【问题讨论】:
标签: node.js postgresql pg-promise
来自pg-promise的作者...
pg-promise 不支持查询取消,因为它是一种解决错误数据库设计或错误查询执行的方法。
PostgreSQL 支持在执行耗时查询时应该使用的事件,因此可以设置一个事件侦听器以在特定数据/视图可用时触发,而不是等待。请参阅LISTEN/NOTIFY 示例。
您可以使用您自己的自定义查询方法扩展pg-promise,该方法会因拒绝而超时(参见下面的示例),但这又是设计问题之上的另一种解决方法。
使用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 */);
然后你可以在每个级别使用db.queryTimeout(query, values, delay)。
或者,如果您使用Bluebird,您可以将.timeout(delay) 链接到任何现有方法:
db.any(query, values)
.timeout(500)
.then(data => {})
.catch(error => {})
另见:
更新
从版本 8.5.3 开始,pg-promise 开始支持查询超时,通过连接对象中的属性 query_timeout。
您可以覆盖默认值:
pgp.pg.defaults.query_timeout = 3000; // timeout every query after 3 seconds
或者在连接对象中指定:
const db = pgp({
/* all connection details */
query_timeout: 3000
});
【讨论】:
.timeout 会拒绝承诺,但 pg-promise 包装了异步代码,该代码在数据库上运行查询,两者都没有拒绝/取消承诺的概念。