基于Node.js事件循环关闭Redis连接。

3

问题/如何遇到它

我正在使用Node.JS编写批处理Lambda函数,涉及两个不同地方的Redis调用。一些批处理项可能永远无法到达第二个Redis调用。由于所有操作都是异步执行的,所以如果在批处理队列为空时关闭连接,任何未来的Redis调用都会失败。该怎么关闭连接?

我的尝试

目前我正在做什么

一旦批处理队列为空,我就会调用:

intervalId = setInterval(closeRedis, 1000);

在超时后的回调函数中,我关闭了Redis连接并清除了间隔:

function closeRedis() {
    redis.client('list', (err, result) => {
        var idle = parseClientList(result, 'idle');

        if (idle > timeout) {
            redis.quit();
            clearInterval(intervalId);
        }
    });
}

这种方法大多数情况下是有效的,但如果只是检查超时,仍然有可能存在其他进程正在运行并且将来可能会进行Redis调用的情况。我希望在事件循环中仅剩下空闲连接时关闭连接。是否有一种方法可以实现这一点?

1个回答

2

我最终使用了process._getActiveHandles()。一旦批处理队列为空,我设置一个间隔,每半秒钟检查是否只剩下最少的进程。如果是这样,我将取消引用redisClient。

redisIntervalId = setInterval(closeRedis, 500);

// close redis client connection if it's the last required process
function closeRedis() {
    // 2 core processes plus Redis and interval
    var minimumProcesses = 4;
    if (process._getActiveHandles().length > minimumProcesses)
        return;

    clearInterval(redisIntervalId);
    redisClient.unref();
}

这种方法的优点是,我可以确保Redis客户端在运行其他重要进程时不会关闭连接。我还可以确保在完成所有重要进程后,客户端不会继续保持事件循环的活动状态。
缺点是_getActiveHandles()是一个未经记录的节点函数,因此可能会在以后被更改或删除。此外,unref()是实验性的,并且在关闭连接时不考虑某些Redis命令。

如果你正在开发一个 lambda 函数,你可以设置 context.callbackwaitsforemptyeventloop = false 来结束函数执行而不必等待连接关闭。 - demian85

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接