ioredis icon indicating copy to clipboard operation
ioredis copied to clipboard

Creating a redis connection keeps the process running indefinitely.

Open ramitmittal opened this issue 5 years ago • 4 comments

Merely creating a redisClient causes the process to keep on running. Ideally, the process should exit.

Steps to reproduce:

const Redis = require("ioredis");

const REDIS_URL = 'redis://localhost:6379';

const redis = new Redis(REDIS_URL);

node version - v14.14.0

ioredis version - 4.19.4

ramitmittal avatar Dec 15 '20 05:12 ramitmittal

Hi @ramitmittal,

This behavior is intentional. The process will keep running as long as there are active handles (see https://github.com/mafintosh/why-is-node-running). To exit the process, you can simply disconnect to Redis by calling redis.quit().

luin avatar Dec 15 '20 05:12 luin

Is there a way to 'unref' redis handles?

ramitmittal avatar Dec 15 '20 05:12 ramitmittal

not sure what is unref.

in nodejs, all network connections will block the process from exit until they all disconnect.

stavalfi avatar Aug 04 '21 20:08 stavalfi

Here's a workaround for anyone running into this. We use redis primarily as a pubsub service which listens for events eternally for use in a WebSocket server. In this case we only want the HTTP service keeping the process alive.

import type { Redis } from "ioredis";

export function unrefRedisClient(redisClient: Redis) {
    const erased = redisClient as any;
    erased.connector.connect = function(connect) {
        return async function(this: unknown, ...args: unknown[]) {
            const connection = await connect.apply(this, args);
            connection.unref();
            return connection;
        };
    }(erased.connector.connect);
    return redisClient;
}

[You have to use lazyConnect: true]

As the author mentioned in #44 this will cause dropped commands in the case there is still work pending. If you are using any of the BR, BL, or BZ commands I definitely do not recommend using this.

laverdet avatar Sep 23 '22 03:09 laverdet

Here's a workaround for anyone running into this. We use redis primarily as a pubsub service which listens for events eternally for use in a WebSocket server. In this case we only want the HTTP service keeping the process alive.

import type { Redis } from "ioredis";

export function unrefRedisClient(redisClient: Redis) {
    const erased = redisClient as any;
    erased.connector.connect = function(connect) {
        return async function(this: unknown, ...args: unknown[]) {
            const connection = await connect.apply(this, args);
            connection.unref();
            return connection;
        };
    }(erased.connector.connect);
    return redisClient;
}

[You have to use lazyConnect: true]

As the author mentioned in #44 this will cause dropped commands in the case there is still work pending. If you are using any of the BR, BL, or BZ commands I definitely do not recommend using this.

can you please explain how to use this, thanks

BSN4 avatar Jan 15 '23 02:01 BSN4

can i just use process.exit() ?

.quit() doesn't doing a thing for me

BSN4 avatar Jan 15 '23 02:01 BSN4