使用 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

Node-Postgres 查询方法未调用其回调函数

将 Async/Await 与 node-postgres 一起使用

为啥我不能使用 node-postgres 从数据库中删除?

node-postgres有个坑

PG(node-postgres)VS。续集