Home > Net >  using Node-Redis throws out error saying Error: Socket already opened'
using Node-Redis throws out error saying Error: Socket already opened'

Time:12-22

I am using redis for the notification service, the redis library is Node-Redis with latest version 4.5.1

const Redis = require('redis');
const redisClient = Redis.createClient({ url:'redis://127.0.0.1'});
class NotificationService {
    async  getNotificationCount(userId){
        let llen = 0;
        try {
            await redisClient.connect();
            const notificationKey = `user:notification:${userId}`;
            llen = await redisClient.lLen(notificationKey);
            redisClient.quit(); 
        } catch(err) {
            console.log("Err:", err);
        }        
        return llen;
    }

    async getNotifications(userId, pageNum, pageSize){
        let offset = (pageNum - 1) * pageSize;
        let lpopList1 = [];
        try {
            await redisClient.connect();
            const notificationKey = `user:notification:${userId}`;
            lpopList1 = await redisClient.lRange(notificationKey, 0, -1);
            redisClient.quit();
        } catch(err) {
            console.log("Err:", err);
        }  
        return lpopList1;
    }
...
}

As noted, there is only one client and is being reused for every connection. In each new request, the new connection is built by 'await redisClient.connect()' and closed by 'redisClient.quit()'

However, sometimes the app throws out the error saying 'Err: Error: Socket already opened'.

why is it happening , a better way to deal with this?

Update: the error happened in circumstance that getNotifications() and getNotificationCount() are being called at the same time. however, when I only called one function at each time, the error is not happening.

So it seems one redis client in this library can not deal with concurrency, any best practice?

CodePudding user response:

Connecting to Redis can be nontrivial, especially when dealing with multi-node topologies, and you should try to reuse your connections as much as possible: instead of connecting and disconnecting at every run, I would suggest to just leave the client connected: node-redis handles reconnections automatically in the event of a network failure, so you don't have to worry about that.

Of course, whether you choose to bind the lifespan of the connection to the entire process or to, perhaps, your NotificationService class is up to you and your business needs.

const Redis = require('redis');
const redisClient = Redis.createClient({ url:'redis://127.0.0.1'});

// ...

await redisClient.connect();

// ...

class NotificationService {
    async  getNotificationCount(userId){
        let llen = 0;
        try {
            const notificationKey = `user:notification:${userId}`;
            llen = await redisClient.lLen(notificationKey);
        } catch(err) {
            console.log("Err:", err);
        }        
        return llen;
    }

    async getNotifications(userId, pageNum, pageSize){
        let offset = (pageNum - 1) * pageSize;
        let lpopList1 = [];
        try {
            const notificationKey = `user:notification:${userId}`;
            lpopList1 = await redisClient.lRange(notificationKey, 0, -1);
        } catch(err) {
            console.log("Err:", err);
        }  
        return lpopList1;
    }

    // ...
}
  • Related