Skip to content

Commit

Permalink
Improve connection timeout. Solve race between closing connection on …
Browse files Browse the repository at this point in the history
…timeout and log entry writing.

Simple approach - idle session is the one that is not used, despite the log success of failure.
Upon failure to log, always close the session.
  • Loading branch information
yosefd committed Mar 30, 2012
1 parent d58da59 commit d21e46a
Showing 1 changed file with 31 additions and 30 deletions.
61 changes: 31 additions & 30 deletions lib/winston-mongodb.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
*
*/

var util = require('util'),
mongodb = require('mongodb'),
winston = require('winston');
var util = require('util');
var mongodb = require('mongodb');
var winston = require('winston');

//
// ### function MongoDB (options)
Expand Down Expand Up @@ -82,10 +82,34 @@ MongoDB.prototype.log = function (level, msg, meta, callback) {
return callback(err, null);
}

// Set a timeout to close the client connection unless `self.keepAlive`
// has been set to true in which case it is the responsibility of the
// programmer to close the underlying connection.
if (self.timeout) {
if (self.timeoutId) {
clearTimeout(self.timeoutId);
}
self.timeoutId = setTimeout(function () {
// The session is idle. Closing it.
self.client.close();
self.state = 'unopened';
}, self.timeout);
}

function onError(err) {
self.emit('error', err);
if (self.timeoutId) {
clearTimeout(self.timeoutId);
}
// Next time try to open new session.
self.client.close();
self.state = 'unopened';
callback(err, null);
}

self._db.collection(self.collection, function (err, col) {
if (err) {
self.emit('error', err);
return callback(err, null);
return onError(err);
}

var entry = {
Expand All @@ -97,39 +121,17 @@ MongoDB.prototype.log = function (level, msg, meta, callback) {

col.save(entry, { safe: self.safe }, function (err, doc) {
if (err) {
self.emit('error', err);
return callback(err, null);
return onError(err);
}

self.emit('logged');
// Delay timeout to start from the last successful log.
self.setTimeout();
return callback(null, true);
callback(null, true);
});
});
});
});
};

MongoDB.prototype.setTimeout = function () {
var self = this;
if (!self.timeout) {
return;
}
if (self.timeoutId) {
clearTimeout(self.timeoutId);
}
//
// Set a timeout to close the client connection unless `self.keepAlive`
// has been set to true in which case it is the responsibility of the
// programmer to close the underlying connection.
//
self.timeoutId = setTimeout(function () {
self.client.close();
self.state = 'unopened';
}, self.timeout);
}

//
// ### function open (callback)
// #### @callback {function} Continuation to respond to when complete
Expand Down Expand Up @@ -186,7 +188,6 @@ MongoDB.prototype.open = function (callback) {
self.state = 'opened';
self._db = db;
flushPending();
self.setTimeout();
}

self.state = 'opening';
Expand Down

0 comments on commit d21e46a

Please sign in to comment.