使用 node-postgres 监听查询超时?
Posted
技术标签:
【中文标题】使用 node-postgres 监听查询超时?【英文标题】:LISTEN query timeout with node-postgres? 【发布时间】:2012-01-05 22:28:40 【问题描述】:我在 Postgresql 9.1 数据库上有一个“文章”表和一个在每次插入时通知通道的触发器。
我想创建一个 node.js 脚本来捕获这些插入并将通知推送到使用 Socket.io 连接的客户端。到目前为止,我正在使用 node-postgres 模块来收听频道,但似乎 LISTEN 查询在大约 10-15 秒后超时并停止捕获插入。当超时发生时,我可以查询新的监听,但我不确定如何正确实现延续。
这是我的 postgresql 通知程序:
CREATE FUNCTION article_insert_notify() RETURNS trigger AS $$
BEGIN
NOTIFY "article_watcher";
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
触发器:
CREATE TRIGGER article_insert_trigger
AFTER INSERT ON article
FOR EACH ROW EXECUTE PROCEDURE article_insert_notify();
还有 node.js 代码:
var pg = require ('pg'),
pgConnection = "postgres://user:pass@localhost/db"
pg.connect(pgConnection, function(err, client)
client.query('LISTEN "article_watcher"');
client.on('notification', function(data)
console.log(data.payload);
);
);
如何确保全时 LISTEN 或如何捕获这些超时以重新发出侦听查询?或者也许 node-postgres 以外的模块提供了更合适的工具来做到这一点?
【问题讨论】:
使用pg-promise,完整的例子和解释:LISTEN / NOTIFY 【参考方案1】:pg-promise
中的永久连接是
db.connect(direct: true)
.then(...)
.catch(...);
【讨论】:
【参考方案2】:我在 node-postgres repo 上得到了我的问题的答案。引用 Brianc 的话:
pg.connect 用于创建池连接。使用连接 确实不支持监听事件的池连接或一个好的 想法虽然。 [...] 要根据定义“监听”连接,必须永久保持打开状态。为了 一个连接永久保持打开它永远不能返回到 连接池。
这种情况下正确的监听方式是使用独立客户端:
var pg = require ('pg'),
pgConnectionString = "postgres://user:pass@localhost/db";
var client = new pg.Client(pgConnectionString);
client.connect();
client.query('LISTEN "article_watcher"');
client.on('notification', function(data)
console.log(data.payload);
);
【讨论】:
【参考方案3】:LISTEN
应该持续会话生命周期或直到您执行UNLISTEN
。因此,只要您的代码正在运行,就应该发送通知。请注意,IIRC,postgresql 没有承诺每个NOTIFY
发送一个通知——如果你有很多插入,它可能会选择发送一个NOTIFY
。不确定 9.1,他们引入了LISTEN
有效负载,所以它可能不太有意义。
【讨论】:
那么15秒超时是客户端问题吗?我可以用 node-postgres 解决这个问题,还是我没有合适的方法来做我想做的事情? 我对节点部分不是很熟悉,我不确定我是否完全理解 pg 和代码发布后整个环境会发生什么......以上是关于使用 node-postgres 监听查询超时?的主要内容,如果未能解决你的问题,请参考以下文章
使用 node-postgres 查询的 Promise 总是返回 undefined
将 Async/Await 与 node-postgres 一起使用