问题/我如何遇到它
我正在Node.JS中编写批处理Lambda函数,该函数在两个不同的地方调用Redis。某些批处理项可能永远不会到达第二个Redis调用。这一切都是异步发生的,因此如果我在批处理队列为空时关闭连接,则任何将来的Redis调用都将失败。如何关闭连接?
我尝试了什么
process.on('beforeExit', callback) - 由于事件循环仍包含Redis连接,因此不会被调用
client.unref() - 如果没有待处理的命令,则关闭连接。不处理未来的电话。
我目前正在做什么
批处理队列为空后,我打电话给:
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调用。当事件循环中只剩下空闲连接时,我想关闭连接。有没有办法做到这一点?
答案 0 :(得分:0)
我最终使用 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命令。