I am facing, "Error: Socket already opened issue" when I am using Redis along with my node.js project.
I am trying to cache database results into Redis cache.. When Redis key is not empty, I will pick records from Redis Key. When its empty, I will pick from DB and set to Redis Key.
Here is my code:
const { response } = require('express');
var express = require('express');
var mysql = require('mysql');
const redis = require('redis');
const client = redis.createClient();
function GetLatestPosts() {
return new Promise(async function(resolve, reject) {
await client.connect();
const value = await client.get('indexitems');
if (value != null) {
await client.disconnect();
resolve(JSON.parse(value));
}
else {
var PostsList;
mysqldb.getConnection(function (err, connection) {
var sql = "CALL PRC_GetPostsList()";
connection.query(sql, async function (err, data, fields) {
if (err) throw err;
PostsList = data[0];
await client.set('indexitems', JSON.stringify(PostsList));
await client.expire('indexitems', 86400);
await client.disconnect();
resolve(PostsList);
});
});
}
})
}
I am facing "Error: Socket already opened issue" randomly. Some times it works without any issue. Some times it shows Error: Socket already opened.
Please help me to resolve this issue. Thanks.
Here is my complete error:
Error: Socket already opened
RedisSocket.connect (/home/ubuntu/Projects/Site/Web/node_modules/@node-redis/client/dist/lib/client/socket.js:48:19)
Commander.connect (/home/ubuntu/Projects/Site/Web/node_modules/@node-redis/client/dist/lib/client/index.js:156:70)
/home/ubuntu/Projects/Site/Web/routes/index.js:224:22
new Promise (<anonymous>)
GetPostItems (/home/ubuntu/Projects/Site/Web/routes/index.js:223:12)
/home/ubuntu/Projects/Site/Web/routes/index.js:23:29
Layer.handle [as handle_request] (/home/ubuntu/Projects/Site/Web/node_modules/express/lib/router/layer.js:95:5)
next (/home/ubuntu/Projects/Site/Web/node_modules/express/lib/router/route.js:137:13)
Route.dispatch (/home/ubuntu/Projects/Site/Web/node_modules/express/lib/router/route.js:112:3)
Layer.handle [as handle_request] (/home/ubuntu/Projects/Site/Web/node_modules/express/lib/router/layer.js:95:5)
The problem occurs as client.connect() is called, whereas the redis client is already connected.
Whenever client.get('indexitems') returns a value, then the connection is correctly closed by await client.disconnect();
However, if there is no value, then an asynchronous call to mySQL is made, and the disconnection is only made in the callback of that request.
As this mySQL call happens asynchronously, the function GetLatestPosts may be executed again before the redis connection is closed, and client.connect() called a second time, provoking the error.
The connection to the redis client might be opened only once when the server starts, and kept opened.
This reduce the overhead of opening a new one at each request, then closing it.
The adapted code might then look like below:
const { response } = require('express');
var express = require('express');
var mysql = require('mysql');
const redis = require('redis');
const client = redis.createClient();
async function start() {
await client.connect();
function GetLatestPosts() {
return new Promise(async function(resolve, reject) {
const value = await client.get('indexitems');
if (value != null) {
resolve(JSON.parse(value));
}
else {
var PostsList;
mysqldb.getConnection(function (err, connection) {
var sql = "CALL PRC_GetPostsList()";
connection.query(sql, async function (err, data, fields) {
if (err) throw err;
PostsList = data[0];
await client.set('indexitems', JSON.stringify(PostsList));
await client.expire('indexitems', 86400);
resolve(PostsList);
});
});
}
})
}
}
start()
client.quit() rather than client.disconnect(), in order to ensure that all commands get executed - as documented.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With