async-redis icon indicating copy to clipboard operation
async-redis copied to clipboard

createClient not work after quit

Open dontbesatisfied opened this issue 4 years ago • 2 comments

Node: v12.18.2 redis: 5.0.5 (docker image) async-redis: 2.0.0

Error occur as " AbortError: BLPOP can't be processed. The connection is already closed. "

This is ample code where an error occurs.

const redis = require('async-redis')

let client = redis.createClient("redis://localhost:6379");

let cnt = 0;

async function reconnect() {
    try {
        await client.quit()
        client = null
        client = redis.createClient("redis://localhost:6379");
        console.log('reconnect');
    } catch (error) {
        console.log(error);
    }
}


(async () => {
    while (true) {
        try {
            
            cnt++

            const v = await client.blpop('*', 1)

            if (cnt%5 === 0) {
                throw Error("Test")
            }
        } catch (error) {
            console.error(error);
            await reconnect()
            
        }
    }
})()

But below code work well.
There seems to be a problem with clients with the same option as they connected before.

is it bug?

const redis = require('async-redis')

let client = redis.createClient("redis://localhost:6379");

let cnt = 0;

async function reconnect() {
    try {
        await client.quit()
        client = null
        client = redis.createClient("redis://localhost:6379", {
            customOption: Date.now(), // Here
        });
        console.log('reconnect');
    } catch (error) {
        console.log(error);
    }
}


(async () => {
    while (true) {
        try {
            
            cnt++

            const v = await client.blpop('*', 1)

            if (cnt%5 === 0) {
                throw Error("Test")
            }
        } catch (error) {
            console.error(error);
            await reconnect()
            
        }
    }
})()

dontbesatisfied avatar Aug 12 '21 07:08 dontbesatisfied

This code also reproduces the bug
const redis = require('async-redis');
let client1 = redis.createClient("redis://localhost:6379"),
    client2 = redis.createClient("redis://localhost:6379");

console.log(
  client1.__redisClient === client2.__redisClient
) // true when it it supposed to be false

;(async () => {
  await client1.quit()
  await client2.info()
})();

Looks like this happen due to the following lines

https://github.com/moaxaca/async-redis/blob/fef4248b89d92d911813d177a96ca7e193379047/src/index.js#L13-L15

using JSON.stringify(args) is wrong since multiple clients could have the same configuration, and thus redisClients.get(serializedArgs) will always return the first created client (due to L14).

Maybe using a Symbol or some uuid (crypto.randomUUID()) is more appropriate.

micalevisk avatar Sep 06 '21 23:09 micalevisk

I just notice that this issue is the same as of #61

micalevisk avatar Sep 06 '21 23:09 micalevisk