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

问题/我是如何遇到它的

我在Node.JS中编写了批处理Lambda函数,它在两个不同的地方调用Redis。 某些批次项目可能永远无法到达第二次Redis呼叫。 这一切都是异步发生的,所以如果我在批处理队列为空时立即关闭连接,则任何未来的Redis调用都将失败。 我如何关闭连接?

我试过了

  • process.on('beforeExit',回调) - 不会被调用,因为事件循环仍然包含Redis连接

  • client.unref() - 如果没有命令挂起,则关闭连接。 不处理未来呼叫。

  • client.on('idle',callback) - 可用,但不推荐使用,可能会遗漏未来的呼叫
  • 我目前在做什么

    一旦批处理队列为空,我打电话给:

    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调用。 当事件循环中只剩下空闲连接时,我想关闭连接。 有没有办法做到这一点?


    我结束了使用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命令。

    链接地址: http://www.djcxy.com/p/52705.html

    上一篇: Close a Redis connection based on Node.js Event loop

    下一篇: Node.JS event loop socket delayed or thread blocked