I have implemented redis cache in my node server.I am running redis docker container locally.I have keys stored in redis container which I am able to see but when I am trying to access then I am failed to get data.
Below is my code:
const redis = require('redis');
let redisClient;
redisClient = redis.createClient('127.0.0.1', 6379);
redisClient.connect();
redisClient.on('error', err => {
console.log('Error ' + err);
});
redisClient.on('connect', () => {
console.log('Connected to Redis');
});
//Saving data here
redisClient.set('Region', 'Asia', (err, reply) => {
if (err) {
console.log('error', err);
}
else {
console.log(reply);
}
});
//Fetching data here
redisClient.get('Region', (err, reply) => {
if (err) {
console.log('error', err);
}
else {
console.log(reply);
}
});
Here even though data is saved successfully in redis but I am not getting console statement after saving data.And I am also unable to fetch data from redis.I am only getting Connected to Redis console log.
Someone let me know what I have done wrong in my code.So far to me code seems fine.
It looks like you are using the node-redis client. In v4, this supports promises. Using promises with async/await should make your code easier to follow:
import { createClient } from 'redis';
try {
const client = createClient();
await client.connect();
await client.set('Region', 'Asia');
const region = await client.get('Region');
console.log(`Region is ${region}`);
await client.quit();
} catch (e) {
console.error('Oh no:');
console.error(e);
}
Related
I have redis installed on my system and its running as well.
from node application, im using below code to work with redis.
redis.js
const redis = require("redis");
let client = redis.createClient(6379, '127.0.0.1', {});
let isRedis = false;
client.on("connect", function () {
console.log(`connected to redis`);
isRedis = true;
});
client.on("error", function (err) {
console.log("redis connection error " + err);
throw err;
});
client.on("end", function (err) {
console.log("redis connection end " + err);
});
module.exports = {
SetRedis,
GetKeys,
GetRedis,
GetKeyRedis,
delRedis
};
im using node index.js command to run the application which should also give me "connected to redis" when the connection is established, but i'm not getting this message on my console .
the npm package is also present in package.json
Node Redis 4.x doesn't allow you to pass in discrete arguments for the host and port. The canonical example of connecting to Redis with Node Redis is this:
import { createClient } from 'redis';
(async () => {
const client = createClient();
client.on('error', (err) => console.log('Redis Client Error', err));
await client.connect();
await client.set('key', 'value');
const value = await client.get('key');
})();
If you want to connect to somewhere other than localhost on port 6379, I recommend using a URL. Like this:
createClient({ url: 'redis://awesome.redis.server:6380' });
But if you want finer control, you can find all the gritty configuration options in the documentation on GitHub.
I guess you are making mistake while making connection.
It should have been
let client = redis.createClient('127.0.0.1', 6379, {});
rather than
let client = redis.createClient(6379, '127.0.0.1', {});
Working redis.js,
const redis = require("redis");
let isRedis = false;
(async () => {
let client = redis.createClient(6379, '127.0.0.1', {});// create config
client.on("connect", function () {
console.log(`connected to redis`);
isRedis = true;
});
client.on("error", function (err) {
console.log("redis connection error " + err);
throw err;
});
client.on("end", function (err) {
console.log("redis connection end " + err);
});
function GetKeyRedis(key) {
return new Promise(function (resolve, reject) {
console.log("dd----",key,isRedis);
if (isRedis) {
client.get(key).then((data,err) => {
if(err){
reject(err);
}
if(data){
resolve(data)
} else {
resolve(false);
}
});
} else {
resolve(false);
}
});
}
module.exports = {
GetKeyRedis
};
await client.connect();
})();
I am JS newbie so this may be some silly trouble. I have a lambda written in NodeJS 10.x and I am trying to add MongoDB Atlas insertion. I have started with this tutorial: https://docs.atlas.mongodb.com/best-practices-connecting-to-aws-lambda/
This is my code:
const MongoClient = require('mongodb').MongoClient;
let cachedDb = null;
function connectToDatabase (uri) {
console.log('Connect to mongo database');
if (cachedDb) {
console.log('Using cached database instance');
return Promise.resolve(cachedDb);
}
return MongoClient.connect(uri)
.then(db => {
console.log('Successful connect');
cachedDb = db;
return cachedDb;
}).catch(err => {
console.log('Connection error occurred: ', err);
callback(err);
});
}
function insertUser(db, email) {
console.log('=> modify database');
return db.collection('users').insertOne({"email" : email})
.then(() => { callback(null, result); })
.catch(err => {
console.log('Insert error occurred: ', err);
callback(err);
});
}
exports.handler = (payload, context, callback) => {
const { email, password } = JSON.parse(payload.body);
context.callbackWaitsForEmptyEventLoop = false;
connectToDatabase(MONGODB_URI)
.then(db => {
console.log('Mongo connected')
insertUser(db, email);
})
.then(result => {
console.log('Mongo insert succeeded', result);
})
.catch(err => {
console.log('Mongo insert failed', err);
return responses.INTERNAL_SERVER_ERROR_500(err, callback, response);
});
console.log('finished mongo stuff');
I can see the following logs in CloudWatch:
START RequestId: 0338d336-7d33-40d5-abc7-1511f1c9ea4c Version: $LATEST
2020-01-11T12:18:00.808Z 0338d336-7d33-40d5-abc7-1511f1c9ea4c INFO Connect to mongo database
2020-01-11T12:18:00.855Z 0338d336-7d33-40d5-abc7-1511f1c9ea4c INFO finished mongo stuff
2020-01-11T12:18:01.416Z 0338d336-7d33-40d5-abc7-1511f1c9ea4c ERROR (node:8) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
END RequestId: 0338d336-7d33-40d5-abc7-1511f1c9ea4c
The item is not inserted in Atlas. I have added more verbose logging but it is not shown. If the mongo connect failed there shall be an error. But it seems that the error handlers are ignored. Where is the problem?
You are very close. Few things are missing
callback function needs to be called from your handler function as the insert function doesn't know about callback.
When you do a .then on a promise and you use curly braces you need to return whatever is in there to send it to the next then (unless you do it in a single line).
db in insert method needs to be db.db()
I would recommend to to use async/await instead of callback style. Here is the equivalent code
exports.handler = async (payload) => {
try {
const { email, password } = JSON.parse(payload.body);
const db = await connectToDatabase(MONGODB_URI);
console.log("Mongo connected");
const result = await insertUser(db, email);
console.log("Mongo insert succeeded", result);
return result;
} catch(err) {
console.error(err);
}
};
When I load my page I want some products to be shown, so I make a GET request and it retrieves them from the database. However, when I refresh the page I notice the old connection remains. How to make sure the old connections close?
Here's my code:
const MongoClient = require('mongodb').MongoClient;
const connection = (closure) => {
return MongoClient.connect(config.connectionString, (err, client) => {
if (err) {
return winston.log('error', now() + err);
}
closure(client);
});
};
...
router.get('/products', (req, res) => {
connection((client) => {
client.db('dbname').collection('collectionname')
.find({})
.toArray()
.then((products) => {
response.data = products;
response.message = "Products retrieved successfully!"
res.json(response);
})
.catch((err) => {
winston.log('error', now() + err);
sendError(err, res);
});
});
});
Well, each time your /products route is called, you do create a new MongoClient instance. In that extent to limit the number of connection to your Database, you may either connect once, and save your MongoClient instance:
let client = undefined;
const connection = (closure) => {
// Return the client if any...
if(client) return closure(client);
return MongoClient.connect(config.connectionString, (err, c) => {
if (err) {
return winston.log('error', now() + err);
}
// Save the client.
client = c;
closure(client);
});
};
...or simply close the MongoClient connection you instantiated once you're done with it:
router.get('/products', (req, res) => {
connection((client) => {
client.db('dbname').collection('collectionname')
.find({})
.toArray()
.then((products) => {
response.data = products;
response.message = "Products retrieved successfully!"
// Close the MongoClient...
client.close();
res.json(response);
})
.catch((err) => {
winston.log('error', now() + err);
sendError(err, res);
// Close the MongoClient...
client.close();
});
});
});
I would advise you to go with the first solution: The MongoClient maintains a connection pool, so having multiple clients does not have any advantages. In addition, it allows you to check whether or not the DB is remotely available, before executing anything else as well (just connect to the DB on your app init(), and save the client instance, and you'll be done).
I'm relatively new to node.js. Trying to test connection to mongodb using mocha framework and mongodb driver.
Node.js version - 6.11.3
Mongodb driver version - 2.2.31
Mondodb version - 3.4.7
Here's my js file:
var should = require("should");
var expect = require('chai').expect;
var cfg = require('../config');
var uri = cfg.mongouri;
var MongoClient = require('mongodb').MongoClient, Logger =
require('mongodb').Logger;
Logger.setLevel('debug');
describe("mongoconnection", function () {
describe("fetch data", function () {
it("should fetch data from db", function (done) {
MongoClient.connect(uri,function(err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
}
db.close();
});
done();
});
});
});
However, this part of the code
function(err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
}
db.close();
}
never gets executed and I can't establish connection, e.g. I don't get neither console log nor exception.
Debug information:
[DEBUG-Connection:9352] 1506430786041 creating connection 0 with options [{"host":HOST,"port":PORT,"size":5,"keepAlive":true,"keepAliveInitialDelay":300000,"noDelay":true,"connectionTimeout":30000,"socketTimeout":360000,"ssl":true,"ca":null,"crl":null,"cert":null,"rejectUnauthorized":false,"promoteLongs":true,"promoteValues":true,"promoteBuffers":false,"checkServerIdentity":true}] { type: 'debug',
message: 'creating connection 0 with options [{"host":HOST,"port":PORT,"size":5,"keepAlive":true,"keepAliveInitialDelay":300000,"noDelay":true,"connectionTimeout":30000,"socketTimeout":360000,"ssl":true,"ca":null,"crl":null,"cert":null,"rejectUnauthorized":false,"promoteLongs":true,"promoteValues":true,"promoteBuffers":false,"checkServerIdentity":true}]',
className: 'Connection',
pid: 9352,
date: 1506430786041 }
also already checked that connection string is correct and I can establish connection to it via another app (groovy script executed in SoapUI).
I am stuck at this point, can someone please help me with this, thanks in advance.
You are calling done() from Mocha outside of the async callback from the MongoClient.connect. So done() is called before it can even connect to the db.
Change your code to this:
it("should fetch data from db", function (done) {
MongoClient.connect(uri,function(err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
}
db.close();
done();
});
});
I have created a mongodb native connection and saved it and then using findOne to query a document.
const Promise = require("bluebird");
const MongoClient = require('mongodb').MongoClient;
let mongoDB = undefined;
const getCollection = (collName) => {
if (mongoDB) {
return Promise.resolve(mongoDB.collection(collName));
} else {
return MongoClient.connect(EXT_CONFS.MONGODB_URL)
.then(db => {
mongoDB = db;
return Promise.resolve(mongoDB.collection(collName));
}).catch(e => {
console.error('Error in MongoDb connection');
});
}
};
const findOne = (collName, filter, options) => {
return getCollection(collName)
.then(collection => {
return collection.findOne(filter, options);
})
.then(doc => {
return Promise.resolve(doc);
}).catch(e => {
console.error(e);
return Promise.reject(e);
});
};
Now this all works fine, but if Mongo ShutsDown / Fails after db client is cached, There is no way to handle error. Error never goes to any catch handler :
console.error('Error in MongoDb connection');
or
console.error(e);
I even tried events :
mongoDB.on('connecting', function () {
console.log('connecting');
});
mongoDB.on('timeout', function (error) {
console.log('timeout!');
});
mongoDB.on('close', function (error) {
console.log('close!');
});
mongoDB.on('error', function (error) {
console.error('Error in MongoDb connection: ' + error);
});
mongoDB.on('connected', function () {
console.log('connected!');
});
mongoDB.on('connection', function () {
console.log('connected!');
});
mongoDB.on('connect', function () {
console.log('connected!');
});
mongoDB.once('open', function () {
console.log('connection open');
});
mongoDB.on('reconnected', function () {
console.log('reconnected');
});
mongoDB.on('disconnected', function () {
console.log('disconnected');
});
but no success still. Using NodeJS 4.5.0, MongoDB-Native driver 2.2.24
You should do something like console.error('Failed to connect to mongodb ',e); you are not outputting the error.
Also some events provide an additional parameter and you are outputting those either. In case of failing to connect to an mongodb server, your application should just notify you it's not the best approach to handle mongodb server start/restart from your application use daemons such as systemd or other process monitoring.
Some events are there to just notify the application that connection was lost or an reconnection is attempted, its up to you to handle what is going to be done when those events are emitted.
You can for example attempt to check mongodb status when an disconnect event is emitted an recreate connection object.
You could wrap the connect statement in a try-catch block.