diff --git a/app.js b/app.js index 4b4e176..5857864 100644 --- a/app.js +++ b/app.js @@ -501,4 +501,30 @@ process.on('uncaughtException', function (err) { logger.error(err); logger.error('Process will exit now.'); process.exit(1); +}); + +// gracefully exit +process.on('SIGINT', function () { + config.maintenance = true; + // disconnect all socket.io clients + Object.keys(io.sockets.sockets).forEach(function (key) { + var socket = io.sockets.sockets[key]; + // notify client server going into maintenance status + socket.emit('maintenance', config.version); + socket.disconnect(true); + }); + var checkCleanTimer = setInterval(function () { + var usersCount = Object.keys(realtime.users).length; + var notesCount = Object.keys(realtime.notes).length; + // check if all users and notes array are empty + if (usersCount == 0 && notesCount == 0) { + // close db connection + models.sequelize.close(); + clearInterval(checkCleanTimer); + // wait for a while before exit + setTimeout(function () { + process.exit(0); + }, 100); + } + }, 100); }); \ No newline at end of file diff --git a/lib/config.js b/lib/config.js index 9f11c5b..5579d61 100644 --- a/lib/config.js +++ b/lib/config.js @@ -78,10 +78,12 @@ function getserverurl() { } var version = '0.4.0'; +var maintenance = config.maintenance || false; var cwd = path.join(__dirname, '..'); module.exports = { version: version, + maintenance: maintenance, debug: debug, urlpath: urlpath, port: port, diff --git a/lib/realtime.js b/lib/realtime.js index a8bef97..1d14270 100644 --- a/lib/realtime.js +++ b/lib/realtime.js @@ -25,7 +25,9 @@ var realtime = { onAuthorizeFail: onAuthorizeFail, secure: secure, connection: connection, - getStatus: getStatus + getStatus: getStatus, + users: users, + notes: notes }; function onAuthorizeSuccess(data, accept) { @@ -70,8 +72,9 @@ function emitCheck(note) { } //actions -var users = {}; -var notes = {}; +var users, notes; +realtime.users = users = {}; +realtime.notes = notes = {}; //update when the note is dirty var updater = setInterval(function () { async.each(Object.keys(notes), function (key, callback) { @@ -536,6 +539,7 @@ function ifMayEdit(socket, callback) { } function connection(socket) { + if (config.maintenance) return; parseNoteIdFromSocket(socket, function (err, noteId) { if (err) { return failConnection(500, err, socket); diff --git a/public/js/index.js b/public/js/index.js index 1d6db92..4ac1b50 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -1825,6 +1825,11 @@ socket.on('error', function (data) { if (data.message && data.message.indexOf('AUTH failed') === 0) location.href = "./403"; }); +var retryOnDisconnect = false; +socket.on('maintenance', function (data) { + if (data == version) + retryOnDisconnect = true; +}); socket.on('disconnect', function (data) { showStatus(statusType.offline); if (loaded) { @@ -1833,12 +1838,15 @@ socket.on('disconnect', function (data) { } if (!editor.getOption('readOnly')) editor.setOption('readOnly', true); + if (retryOnDisconnect) + socket.connect(); }); socket.on('reconnect', function (data) { //sync back any change in offline emitUserStatus(true); cursorActivity(); socket.emit('online users'); + retryOnDisconnect = false; }); socket.on('connect', function (data) { personalInfo['id'] = socket.id;