Close a Redis connection based on Node.js Event loop

Issue/ How I ran into it

I'm writing a batch processing Lambda function in Node.JS that makes calls to Redis in two different places. Some batch items may never reach the second Redis call. This is all happening asynchronously, so if i close the connection as soon as the batch queue is empty, any future Redis calls would fail. How do I close the connection?

What i've tried

  • process.on('beforeExit', callback) -- Doesn't get called as the event loop still contains the Redis connection

  • client.unref() -- Closes connection if no commands are pending. Doesn't handle future calls.

  • client.on('idle', callback) -- Works but is deprecated and may still miss future calls
  • What I'm currently doing

    Once the batch queue is empty, I call:

    intervalId = setInterval(closeRedis, 1000);
    

    I close the Redis connection and clear the interval in the callback after a timeout:

    function closeRedis() {
        redis.client('list', (err, result) => {
            var idle = parseClientList(result, 'idle');
    
            if (idle > timeout) {
                redis.quit();
                clearInterval(intervalId);
            }
        });
    }
    

    This approach mostly works, but if just checking for a timeout, there is still a chance that other processes are going on and a Redis call may be made in the future. I'd like to close the connection when there's only an idle connection remaining in the event loop. Is there a way to do this?


    I ended up using process._getActiveHandles() . Once the batch queue is empty, I set an interval to check every half a second if only the minimum processes remain. If so I unref the 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();
    }
    

    The advantage of this approach is that I can be sure Redis client will not close the connection while other important processes are running. I can also be sure that the client won't keep the event loop alive after all the important processes have been completed.

    The downside is _getActiveHandles() is an undocumented node function so it may get changed or removed later. Also, unref() is experimental and doesn't consider some Redis commands when closing the connection.

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

    上一篇: Node.js作为服务器脚本

    下一篇: 基于Node.js事件循环关闭Redis连接