IOredis Connection timeout error in Nodejs - node.js

IOredis Connection timeout error in Nodejs.
We are using ioredis npm, When we are trying to getting the data from redis, we are getting "Connection is Closed" errors.
Actually, in calling the hnormalget() function is giving Connection is Closed error.
var redis = require('ioredis');
var config = require('./../../config');
var redisConfig = config.database;
var clientRead = Promise.promisifyAll(redis.createClient({
port: config.database.redisPort,
host: config.database.redisHost,
prefix: config.database.redisPrefix,
password: config.database.redisPassword,
connectionName: 'redisDB-gpRedisCacheRead',
db:10,
readOnly: true,
keepAlive: 1,
retryStrategy : function retryStrategy(times) {
log.error("Redis retry strategy called for gpRedisCache.js...44")
if (typeof times != "number") {
// Manual Reconnect would be require
// redis.connect()
return new Error('Redis Retry time exhausted');
}
const delay = Math.min(times * 50, 2000);
return delay;
}
}));
var DBNUM = config.redis.GPDatabaseNum;
clientRead.on('connect', function() {
clientRead.select(DBNUM, function(e, r) {
if (e) {
log.error(`Error in redis Read select db server/lib/gpRedisCache.js: ${e}`);
clientRead.end(true); //also initiate reconnection
} else {
// console.log('clientRead connected');
}
});
}); //end of client.on('connect')
clientRead.on('error', function(err) {
log.error(`Error in redis connection on file gpRedisCache.js:95: ${err}`);
clientRead.end(true); //also initiate reconnection here
});
var redisCacheSeparateReadWritePooledConn = {
hnormalget: (hashKey, key, cb) => {
return clientRead.hget(hashKey, key).then((data) => {
return { err: null, data };
}).catch(err => {
return { err };
});
},
}
//TILL above is the handling for single conn
module.exports = redisCacheSeparateReadWritePooledConn;

Related

Jest Testing of Redis Service

I have a number of services in my Nodejs repo that uses Redis. I'm trying to improve the quality of my development and therefore am starting to implement Jest testing. However, I cannot get the Jest tests to connect to the (test) Redis database during testing.
I've tried using a continually running Redis server on the CI/CD (Jenkins) server and I have tried using this library "Redis-Memory-Server" which is meant to create a Redis server instance during testing. I've spent many hours this week trying to fix this issue and have no idea why it's happening.
Any help is greatly appreciated.
Redis Management File
// Redis database module for Unseen Games
const redis = require('redis');
const { promisifyAll } = require('bluebird');
const _ = require('lodash');
promisifyAll(redis);
//Contains all the redis clients currently made
var event_status = "unconnected";
var timeout_cleared = false;
const clients: any = {};
let connectionTimeout;
function throwTimeoutError() {
connectionTimeout = setTimeout(() => {
throw new Error('Redis connection failed');
}, 10000);
}
function instanceEventListenersRedis({ conn }) {
conn.on('connect', () => {
// console.log('CacheStore - Connection status: connected');
event_status = "connected";
timeout_cleared = false;
clearTimeout(connectionTimeout);
});
conn.on('ready', () => {
event_status = "ready";
// console.log('CacheStore - Connection status: ready');
})
conn.on('end', () => {
event_status = "disconnected";
// console.log('CacheStore - Connection status: disconnected');
//TODO: The below code should stop Jest from hanging when testing the code, but doesn't, fix?
// if(!timeout_cleared) {
// throwTimeoutError();
// }
});
conn.on('reconnecting', () => {
event_status = "reconnecting";
// console.log('CacheStore - Connection status: reconnecting');
clearTimeout(connectionTimeout);
});
conn.on('error', (err) => {
event_status = "error";
// console.log('CacheStore - Connection status: error ', { err });
throwTimeoutError();
});
}
export const redisInit = async () => {
if(process.env.BALENA==="1" || process.env.DEVICE === "local"){
const cacheInstance = redis.createClient(process.env.REDIS_URL);
clients.cacheInstance = cacheInstance;
instanceEventListenersRedis({ conn: cacheInstance });
} else if(process.env.DEVICE =="demo") {
event_status = "connecting"
const cacheInstance = redis.createClient({host: process.env.REDIS_HOST, port: process.env.REDIS_PORT});
clients.cacheInstance = cacheInstance;
instanceEventListenersRedis({ conn: cacheInstance });
} else {
throw Error;
}
};
export const redisCheckConnection = () => {
if(process.env.REDIS == "true") {
return event_status;
} else {
return "readyo";
}
}
export const redisGetClients = () => clients;
export const redisCloseConnections = () => {
timeout_cleared = true;
_.forOwn(clients, (conn) => conn.quit());
}
jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
setupFiles: ['dotenv/config'],
transform: {}
};
process.env = Object.assign(process.env, {
REDIS: 'true',
DEVICE: 'demo'
});

IOredis Connection is Closed error in Nodejs

IOredis Connection is Closed error in Nodejs. We are using ioredis npm, When we are trying to getting the data from redis, we are getting "Connection is Closed" errors.
Actually, in calling the hnormalget() function is giving Connection is Closed error.
var redis = require('ioredis');
var config = require('./../../config');
var redisConfig = config.database;
var clientRead = Promise.promisifyAll(redis.createClient({
port: config.database.redisPort,
host: config.database.redisHost,
prefix: config.database.redisPrefix,
password: config.database.redisPassword,
connectionName: 'redisDB-gpRedisCacheRead',
db:10,
readOnly: true,
keepAlive: 1,
retryStrategy : function retryStrategy(times) {
log.error("Redis retry strategy called for gpRedisCache.js...44")
if (typeof times != "number") {
// Manual Reconnect would be require
// redis.connect()
return new Error('Redis Retry time exhausted');
}
const delay = Math.min(times * 50, 2000);
return delay;
}
}));
var DBNUM = config.redis.GPDatabaseNum;
clientRead.on('connect', function() {
clientRead.select(DBNUM, function(e, r) {
if (e) {
log.error(`Error in redis Read select db server/lib/gpRedisCache.js: ${e}`);
clientRead.end(true); //also initiate reconnection
} else {
// console.log('clientRead connected');
}
});
}); //end of client.on('connect')
clientRead.on('error', function(err) {
log.error(`Error in redis connection on file gpRedisCache.js:95: ${err}`);
clientRead.end(true); //also initiate reconnection here
});
var redisCacheSeparateReadWritePooledConn = {
hnormalget: (hashKey, key, cb) => {
return clientRead.hget(hashKey, key).then((data) => {
return { err: null, data };
}).catch(err => {
return { err };
});
},
}
//TILL above is the handling for single conn
module.exports = redisCacheSeparateReadWritePooledConn;

SQL select all statement in a node.js application returns a tedious deprecated error

So I went to the Microsoft documentation for node.js and trying to connect to a database and I went through step by step, installed tedious and when I try to run my code it's throwing an error saying:
tedious deprecated In the next major version of tedious, creating a new Connection instance will no longer establish a connection to the server automatically. Please use the new connect helper function or call the .connect method on the newly created Connection object to silence this message. internal\process\task_queues.js:79:11.
Does anyone know what this means?
CODE:
const Discord = require('discord.js');
const bot = new Discord.Client();
const token = 'HIDDEN';
bot.on('ready', () => {
console.log('This bot is online!');
var Connection = require('tedious').Connection;
var config = {
server: '', //update me
authentication: {
type: 'default',
options: {
userName: '', //update me
password: '' //update me
}
},
options: {
// If you are on Microsoft Azure, you need encryption:
encrypt: true,
database: '' //update me
}
};
var connection = new Connection(config);
connection.on('connect', function(err) {
// If no error, then good to proceed.
if(!err)
{
console.log("Connected");
executeStatement();
}
});
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
function executeStatement() {
request = new Request("SELECT * from tblCustomer;", function(err) {
if (err) {
console.log(err);}
});
var result = "";
request.on('row', function(columns) {
columns.forEach(function(column) {
if (column.value === null) {
console.log('NULL');
} else {
result+= column.value + " ";
}
});
console.log(result);
result ="";
});
request.on('done', function(rowCount, more) {
console.log(rowCount + ' rows returned');
});
connection.execSql(request);
}
})
bot.login(token);

ReactNative MQTT Listener

I have the following code excerpt:
client.on ('message', function (msg) {
// ....
});
Can someone tell me how I get the value of msg from this function and can access it from outside.
I tried but it doesn't work:
this.setState ({msg: msg})
You can make an MQTT manager and use it.
Example
module.exports = { // cached singleton instance
QOS: 1, // Only 0 and 1 supported by Rabbit
props: null,
create(userID, connectionProps = {}) {
if (userID && connectionProps) {
// http://www.hivemq.com/demos/websocket-client/
this.onConnectionOpened = this.onConnectionOpened.bind(this);
this.onConnectionClosed = this.onConnectionClosed.bind(this);
this.onError = this.onError.bind(this);
this.onMessageArrived = this.onMessageArrived.bind(this);
this.disconnect = this.disconnect.bind(this);
const deviceId = this.randIdCreator()
.replace(/[^a-zA-Z0-9]+/g, '');
this.conProps = _.extend({
clientId: `realtime.${userID}.${deviceId}`,
channelToUse: `mqtt-subscription-realtime.${userID}`,
auth: false,
clean: true, // clean session YES deletes the queue when all clients disconnect
}, connectionProps);
/* create mqtt client */
MQTT.createClient(this.conProps)
.then((client) => {
this.client = client;
client.on('closed', this.onConnectionClosed);
client.on('error', this.onError);
client.on('message', this.onMessageArrived);
client.on('connect', this.onConnectionOpened);
client.connect();
}).catch((err) => {
console.error(`MQTT.createtClient error: ${err}`);
});
}
},
...
onMessageArrived(message) {
if (message) {
console.log(`MQTT New message: ${JSON.stringify(message)}`)
}
}
...
Usage
import MqttNotificationsManager from './realtimeManager';
// init realtime
MqttNotificationsManager.create(
'bob',
{
uri: 'mqtt://test.mosquitto.org:1883',
},
);

share mqtt client object between files

I connect to MQTT this way:
//mqtt.js
const mqtt = require('mqtt');
var options = {
//needed options
};
var client = mqtt.connect('mqtt://someURL', options);
client.on('connect', () => {
console.log('Connected to MQTT server');
});
I want to export the client object this way:
//mqtt.js
module.exports = client;
So that I can import it in other files and make use of it this way:
//anotherFile.js
const client = require('./mqtt');
client.publish(...)
However, we all know that this will not work! How can I achieve this ?
Update
I tried promise and get a very strange behavior. When I use the promise in the same file (mqtt.js) like the code below, everything is OK:
//mqtt.js
const mqtt = require('mqtt');
var mqttPromise = new Promise(function (resolve, reject) {
var options = {
//needed options
};
var client = mqtt.connect('mqtt://someURL', options);
client.on('connect', () => {
client.subscribe('#', (err) => {
if (!err) {
console.log('Connected to MQTT server');
resolve(client);
} else {
console.log('Error: ' + err);
reject(err);
}
});
});
});
mqttPromise.then(function (client) {
//do sth with client
}, function (err) {
console.log('Error: ' + err);
});
But when I export the promise and use it in another file, like this:
//mqtt.js
//same code to create the promise
module.exports = mqttPromise;
//anotherFile.js
const mqttPromise = require('./mqtt');
mqttPromise.then(function (client) {
//do sth with client
}, function (err) {
console.log('Error: ' + err);
});
I get this error:
TypeError: mqttPromise.then is not a function
You can probably achieve your goal creating 2 files, one for handling mqtt methods and another to manage the connection object.
Here's the file for the mqtt handler:
//mqttHandler.js
const mqtt = require('mqtt');
class MqttHandler {
constructor() {
this.mqttClient = null;
this.host = 'YOUR_HOST';
this.username = 'YOUR_USER';
this.password = 'YOUR_PASSWORD';
}
connect() {
this.mqttClient = mqtt.connect(this.host, {port: 1883});
// Mqtt error calback
this.mqttClient.on('error', (err) => {
console.log(err);
this.mqttClient.end();
});
// Connection callback
this.mqttClient.on('connect', () => {
console.log(`mqtt client connected`);
});
this.mqttClient.on('close', () => {
console.log(`mqtt client disconnected`);
});
}
// // Sends a mqtt message to topic: mytopic
sendMessage(message, topic) {
this.mqttClient.publish(topic, JSON.stringify(message));
}
}
module.exports = MqttHandler;
Now lets use the exported module to create a mqtt client connection on another file:
//mqttClient.js
var mqttHandler = require('./mqttHandler');
var mqttClient = new mqttHandler();
mqttClient.connect();
module.exports = mqttClient;
With this exported module you can now call your client connection object and use the methods created in the mqttHandler.js file in another file :
//main.js
var mqttClient = require('./mqttClient');
mqttClient.sendMessage('<your_topic>','<message>');
Although there may be a better method to perform your task, this one worked pretty well for me...
Hope it helps!
cusMqtt.js
const mqtt = require("mqtt");
function prgMqtt() {
const options = {
port: 1883,
host: "mqtt://xxxxxxx.com",
clientId: "mqttjs_" + Math.random().toString(16).substr(2, 8),
username: "xxxxxx",
password: "xxxxxx",
keepalive: 60,
reconnectPeriod: 1000,
protocolId: "MQIsdp",
protocolVersion: 3,
clean: true,
encoding: "utf8",
};
prgMqtt.client = mqtt.connect("mqtt://xxxxxxxx.com", options);
prgMqtt.client.on("connect", () => {
prgMqtt.client.subscribe("Room/Fan");
console.log("connected MQTT");
});
prgMqtt.client.on("message", (topic, message) => {
console.log("message is " + message);
console.log("topic is " + topic);
// client.end();
});
}
exports.prgMqtt = prgMqtt;
index.js/main program call
const { prgMqtt } = require("./startup/cusMqtt");
prgMqtt();
another .js
const { prgMqtt } = require("../startup/cusMqtt");
router.get("/:id", async (req, res) => {
prgMqtt.client.publish("Room/Reply", "Replied Message");
});

Resources