I'm writing a small Node to just monitor MongoDB by making a simple query via Mongoose. If something is returned, the service is deemed as available. Here is my script
var res;
var logPrefix = '[MongoDB]';
var counter = 0;
var mongoose = require('mongoose');
// Simple schema and model for getting a companyprofiles document
var companyProfile = new mongoose.Schema({
_id: String
});
companyProfile.virtual('Id').get(function () {return this._id});
function closeConnection() {
console.log('8');
mongoose.connection.close(function () {
console.log('9');
console.log('%s Closed connection%d', logPrefix, counter);
});
}
function connectAndCheckHealth() {
console.log('2');
mongoose.connect('mongodb://localhost:27017/testdb');
console.log('3');
mongoose.connection.on('error', function(err) {
console.log('%s Error connecting to DB:\n%s %s', logPrefix, logPrefix, err);
res.send(503, 'ERR');
});
mongoose.connection.on('open', function() {
mongoose.connection.db.serverConfig.options.auto_reconnect = false;
});
console.log('4');
mongoose.connection.on('connected', checkHealth);
console.log('5');
mongoose.connection.on('close', function() {
console.log('%s Connection to MongoDB closed %d', logPrefix, counter);
});
}
function checkHealth() {
console.log('6');
cpModel = mongoose.model('companyProfile', companyProfile, 'companyprofiles');
cpModel.findById('spin', handleModelResponse);
}
function handleModelResponse(error, doc) {
console.log('7');
closeConnection();
console.log('10');
if (error !== null) {
console.log('11');
console.log('%s Error handling response from model:\n%s %s', logPrefix, logPrefix, error);
res.send(503, 'ERR');
} else {
console.log('12');
if (doc.Id.match(/company1/)) {
console.log('13');
console.log('%s App status is ok', logPrefix);
res.send(200, 'OK');
} else {
console.log('14');
console.log('%s Couldn\'t find the spin company profile. Found %s', logPrefix, doc.Id);
res.send(503, 'ERR');
}
}
}
module.exports = {
health: function(response) {
counter++;
var date = new Date();
console.log('%s Retrieving health from MongoDB at %s', logPrefix, date);
res = response;
console.log(mongoose.connection);
console.log('1');
connectAndCheckHealth();
console.log('15');
}
}
As you can see, I've peppered the script with console.log lines with numbers to try and work out the control flow. Here's the output:
1
2
3
4
5
15
6
6
6
7
8
[MongoDB] Connection to MongoDB closed 3
[MongoDB] Connection to MongoDB closed 3
[MongoDB] Connection to MongoDB closed 3
9
[MongoDB] Closed connection3
10
12
13
[MongoDB] App status is ok
7
8
9
[MongoDB] Closed connection3
10
12
13
[MongoDB] App status is ok
/home/GTP/healthcheck/node_modules/mongoose/lib/utils.js:413
throw err;
^
Error: Can't set headers after they are sent.
Notice that 6 appears three times (the callback after we have connected). I can't tell why we are opening multiple connections. I've turned autoconnect off and am closing the connection after every request.
Any help would be greatly appreciated.
Mongoose opens a pool of 5 connections by default; if you only want a single connection you can change your connect call to be:
mongoose.connect('mongodb://localhost:27017/testdb', { server: { poolSize: 1 }});
db.once('open') worked for me.
While testing my page, I had noticed that double and rapid form submits were triggering errors about the headers already sent. This stopped that.
Related
In the following code, the MongoClient is already closed when the callback function of collection.insert() is executed. So I'm expecting collection.insert() not to work and throw an error.
But it's working, collection.insert() works fine even when MongoClient is already closed.
How is this possible?
My code :
const MongoClient = require('mongodb').MongoClient,
connectionUrl = 'mongodb://localhost:27017';
myDatabase = 'library',
myCollection = 'books';
MongoClient.connect(connectionUrl, function(Connectionerror, client) {
if (Connectionerror) {
throw Connectionerror;
}
console.log("Successfully connected to server");
var database = client.db(myDatabase),
collection = database.collection(myCollection);
var book = {Author:"Mark Twain",Title:"Tom Sawyer"};
collection.insert(book,function(InsertionError,result){
if(!InsertionError) {
console.log("Success : "+result.ops.length+" book(s) inserted!");
} else console.log("An insertion error was encountered!");
});
client.close();
console.log();
console.log("Mongo Client is closed");
console.log();
});
Execution :
$ node app-test.js
Successfully connected to server
Mongo Client is closed
Success : 1 book(s) inserted!
The book has been inserted AFTER the client has been closed. How is this possible ?
Now, on the other hand, if there are two levels of callbacks (a collection.insert() under a collection.findOne()) then it raises an error, like I would expect (MongoError : server instance pool was destroyed):
const MongoClient = require('mongodb').MongoClient,
connectionUrl = 'mongodb://localhost:27017';
myDatabase = 'library',
myCollection = 'books';
MongoClient.connect(connectionUrl, function(Connectionerror, client) {
if (Connectionerror) {
throw Connectionerror;
}
console.log("Successfully connected to server");
var database = client.db(myDatabase),
collection = database.collection(myCollection);
var book = {Author:"Mark Twain",Title:"Tom Sawyer"};
collection.findOne(book,function(QueryError,bookToFind){
if(!QueryError) {
if (bookToFind != null) {
console.log("This book already exists !");
} else {
collection.insert(book,function(InsertionError,result){
if(!InsertionError) {
console.log("Success : "+result.ops.length+" books inserted!");
} else {
console.log("An insertion error was encountered!");
console.log(InsertionError.stack);
}
});
}
} else console.log("A request errror was encountered !");
});
client.close();
console.log();
console.log("Mongo Client is closed");
console.log();
});
Execution :
$ node app-test2.js
Successfully connected to server
Mongo Client is closed
An insertion error was encountered!
MongoError: server instance pool was destroyed
(...)
The second example works same as the first. 1. Find query gets executed. 2. Till the response comes from database client.close() gets executed. 3. Now when the response is received by the first query, then second query will throw the exception/ error because step2 has closed the connection.
Infact your console.log answers your own question.
Hey uh I am having an issue and I think this is probably related to net.createserver.
The issue is that whenever the first client joins after that another second client joins, the first client can control the second client and then the first client disconnects because the socket(end) event gets triggered. Is it related to sockets or something or the server can't handle two connections? Please help
The code:
handleGame: function() {
console.log(log.success('The source is starting!'));
var server = net.createServer(function(socket) {
console.log('A client has connected' + "\r\n");
socket.setEncoding('utf8')
global.clientObjz = new client(socket);
game.addClient(clientObjz);
socket.on('data', function(data) {
data = data.toString().split('\0')[0];
console.log('Incoming data: ' + data + "\r\n")
if (data == "<msg t='sys'><body action='verChk' r='0'><ver v='153' /></body></msg>" | data == "<msg t='sys'><body action='rndK' r='-1'></body></msg>" | data.startsWith("<msg t='sys'><body action='login' r='0'>")) {
parseXml(data, function(err, result) {
var type = result.msg['$'].t,
action = result.msg.body[0]['$'].action;
var method = Game.xmlHandlers[type][action];
if (typeof Game[method] == 'function') {
Game[method](data, client);
}
});
}
var dataType = data.charAt(0);
if (dataType == '%') {
game.handleraw(data, clientObjz);
}
});
socket.on('end', function() {
game.removeClient(socket);
console.log('A client has disconnected');
});
socket.on('error', function(err) {
console.log(err);
});
});
server.listen(Game1, "localhost", function() {
console.log('Server is listening on port 6113');
});
}
//this code is another file as i am calling it by game.clients.push
addClient: function(client) {
if (client) {
self.clients.push(client);
}
}
Yes, it's a clubpenguin emulator
full code: https://github.com/dev3211/bingojs
You need to implement socket channels if you are doing this only with NodeJS net.createServer. If you want it simple, you could look for something using express.js, something like this: https://medium.com/factory-mind/websocket-node-js-express-step-by-step-using-typescript-725114ad5fe4
I am new with the node js.
I am using node js with express.
I am create connection on server side via below code.
io.sockets.on('connection', function (socket) {
// console.log('A new socket connected with id : '+socket.id);
socket.on('error',function(e){
// console.log(e);
})
socket.on('disconnect',function(e){
// console.log( " \n disconnect \n ",e);
})
socket.on('UserRoom', function(data){
var user_id = data.user_id;
if(socket.adapter.rooms[user_id]===undefined)
{
console.log('Hey i am connected to server for User id => '+user_id);
socket.join(user_id);
}
else
{
console.log('Hey i am already connected to User id');
}
});
socket.on('JoinDraft', function(data)
{
var game_unique_id = data.game_unique_id;
socket.join(game_unique_id);
});
});
app.post('/game_update', function(req, res)
{
var target = true;
var response = '';
req.on('data', function (data) {
response += data;
});
req.on('end', function () {
res.sendStatus(200);
var result = JSON.parse(response);
game_update(result);
});
});
function game_update( result )
{
var game_unique_id = result ;
io.to(game_unique_id).emit('game_update', {"game_unique_id": game_unique_id});
};
client side code :- for joining room
function joinDraft_socket() {
// console.log(gameObj);
socket.emit('JoinDraft',{"game_unique_id" : gameObj.game_unique_id});
}
for getting node response , we have
socket.on('game_update', function(data) {
if(data.game_unique_id == gameObj.game_unique_id) {
console.log('Trigger to update ', data);
isYourPick();
}
});
Server node emit data single time to any room ( game_unique_id) then clients are receiving server ping multiple times.
Please let me know if any one face this kind of issue and how they resolved it.
Below is image of console after single update of server node , client receive multiple hits
Any help is appreciate ...
Thanks in Advance
I'm new to message queue's and i'm trying to connect to a rabbit mq instance that was setup for me using https://github.com/squaremo/amqp.node and i'm definitely on the struggle bus.
I took the example from here and i'm trying to plug my values in and I'm getting no where.
Here's the info I was given:
Server: myserver
Queue: uinotification
username: myuser
password: mypass
Here's my attempt at using this example but I think instead of having to assert the queue i need to bind to it (i think).
Here's the docs for bindQueue: http://www.squaremobius.net/amqp.node/doc/channel_api.html#toc_39
I think i'm confused by the exchange piece.
amqp.connect('amqp://myuser:mypass#myserver').then(function(conn) {
process.once('SIGINT', function() { conn.close(); });
return conn.createChannel().then(function(ch) {
var ok = ch.assertExchange('logs', 'fanout', {durable: false});
ok = ok.then(function() {
//return ch.assertQueue('', {exclusive: true});
return ch.bindQueue('uinotification', 'logs', '');
});
/*ok = ok.then(function(qok) {
console.log('qok = ');
console.log(qok);
return ch.bindQueue(qok.queue, 'logs', '').then(function() {
return qok.queue;
});
});*/
ok = ok.then(function(queue) {
console.log('queue = ');
console.log(queue);
return ch.consume(queue, logMessage, {noAck: true});
});
return ok.then(function() {
console.log(' [*] Waiting for logs. To exit press CTRL+C');
});
function logMessage(msg) {
console.log(" [x] '%s'", msg.content.toString());
}
}).catch(function(err) {
console.error('err = '+err);
});
}).then(null, console.warn).catch(function(err) {
console.error('connect err = '+err);
});
Here's the error I get with the above code:
Channel closed by server: 404 (NOT-FOUND) with message "NOT_FOUND - no previously declared queue"
A queue has to exist before you can bind to it, thus asserting it into existence first is actually what you need to do before binding to it.
Note that the settings for the queue have to be exactly the same as the ones the queue has been first created with.
I tried out last 3 days with the below issue. Kindly help me to resolve the issue,
>Error: Unexpected close
at succeed (/usr/local/lib/node_modules/amqplib/lib/connection.js:259:13)
at onOpenOk (/usr/local/lib/node_modules/amqplib/lib/connection.js:241:5)
at /usr/local/lib/node_modules/amqplib/lib/connection.js:160:32
at /usr/local/lib/node_modules/amqplib/lib/connection.js:154:12
at Socket.recv (/usr/local/lib/node_modules/amqplib/lib/connection.js:480:12)
at Socket.g (events.js:180:16)
at Socket.EventEmitter.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:407:10)
at emitReadable (_stream_readable.js:403:5)
at readableAddChunk (_stream_readable.js:165:9)
I am using amqplib + node js. Whenever i started the server i got the above error with a time interval. Maximum it will occurs at 5 mins interval.
amqplib = amqplib.connect('amqp://'+rabit_host).then(function(conn)
{
amqpconnection = conn;
});
io.sockets.on('connection', function(client)
{
client.on('receivemsg', function(arg)
{
amqpconnection.createConfirmChannel().then(function(channelObjSuccess)
{
channelObjSuccess.assertQueue(queue_name,{durable:false,autoDelete:true});
client.assignObj = channelObjSuccess;
channelObjSuccess.consume(queue_name, function(msg)
{
var encodemsg = msg.content.toString();
var json_msg = JSON.parse(encodemsg);
client.emit('chatrecive',json_msg);
}).then(function(){
console.log("Receive Consiuume Close");
});
});
});
client.on('loginentry', function(arg)
{
amqpconnection.createConfirmChannel().then(function(channelObjSuccess) {
channelObjSuccess.assertQueue(queue_name,{durable:false,autoDelete:true});
});
});
client.on('sendmsg', function(arg)
{
var payload_stringify = JSON.stringify(arg);
amqpconnection.createConfirmChannel().then(function(channelObjSuccess) {
channelObjSuccess.assertQueue(queue_name,{durable:false,autoDelete:true});
channelObjSuccess.sendToQueue(queue_name, new Buffer(payload_stringify), {},
function(err, ok)
{
if (err !== null)
console.log('Message Send Failure! ');
else
{
channelObjSuccess.close();
}
});
});
});
client.on('disconnect', function()
{
try {
console.log("AMPQ Connection Closed - Disconnect");
if(typeof(client.assignObj)!=undefined)
{
client.assignObj.close();
}
}
catch (alreadyClosed) {
console.log("RabbitMQ Connection Already Closed " + alreadyClosed.stackAtStateChange);
}
});
});
server.listen(port);
I think i found the answer, might be the issue is with the heartbeat as option while connecting to the AMQP.
Eg:
url = "amqp://turtle.rmq.cloudamqp.com/bqftjxzn?heartbeat=45";