From 8c61a1980c973c649a2d9b3b9da67f2a680f4139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Sun, 4 Oct 2015 11:43:48 +0200 Subject: Improved exception tolerance, added logging to a file, removed old code, simplified handling of common requests. --- web/main.js | 121 ++++++++++++++++++++---------------------------------------- 1 file changed, 40 insertions(+), 81 deletions(-) (limited to 'web') diff --git a/web/main.js b/web/main.js index 9f06e88..931a550 100644 --- a/web/main.js +++ b/web/main.js @@ -4,7 +4,21 @@ var engine = require('engine.io'), Promise = require('bluebird'), log4js = require('log4js'); -var logger = log4js.getLogger(); // TODO: log to a file +log4js.loadAppender('file'); +log4js.addAppender(log4js.appenders.file('web.log'), 'log'); +var logger = log4js.getLogger('log'); + +Promise.onPossiblyUnhandledRejection(function (error) { + var msg = 'Unhandled promise rejection: ' + error; + if ((error instanceof Error) && (typeof error.stack === 'string')) msg += '\n' + error.stack; + logger.error(msg); +}); + +process.on('uncaughtException', function (error) { + var msg = 'Uncaught exception: ' + error; + if ((error instanceof Error) && (typeof error.stack === 'string')) msg += '\n' + error.stack; + logger.error(msg); +}); http_server.listen(8083); @@ -41,34 +55,9 @@ var sessions = { // sid: sessions description {sid: string, lastActivity: Date.now(), socket: net.Socket} }; -// GUI action handlers, keyed by the action name, values are functions that take the session and the message +// GUI action handlers, keyed by the action name, values are functions that take the session and the message, or truthy values var guiHandlers = { - // TODO: list_problems is outside sessions for now; later it must become session-aware - 'list_problems': function actionListProblems(session, message) { - var tid = message['tid']; // remember any TID that is set - delete message['tid']; // delete any TID, we must use an internal one when sending to Python, because it must be unique over all connected sessions - logger.debug('Received a list_problems request from GUI'); - sendDataToPython(message).then( - function listProblemsRequestOK(response) { - if ((typeof tid !== 'undefined') && (tid !== null)) response['tid'] = tid; - else delete response['tid']; - session.send(response); - }, - function listProblemsRequestFailed(err) { - var response = { - 'code': -30 - }, - reason; - logger.debug('Failed to request list_problems from Python'); - if ((typeof tid !== 'undefined') && (tid !== null)) response['tid'] = tid; - if ((typeof err === 'object') && (err !== null)) reason = err.toString(); - else reason = '' + err; - response['message'] = 'List-problems request failed: ' + reason; - session.end(response); - } - ).done(); - }, - + // special-case action handlers 'login': function actionLogin(session, message) { // first-time connect: login var tid = message['tid']; // remember any TID that is set @@ -109,11 +98,6 @@ var guiHandlers = { ).done(); }, - //'resume': function actionResume(session, message) { - // // reconnect: resume the session after unexpected disconnect - // - //}, - 'logout': function actionLogout(session, message) { // logout, the user quit the app logger.debug('Logout GUI'); @@ -122,50 +106,17 @@ var guiHandlers = { }).done(); }, - 'activity': function actionActivity(session, message) { - logger.debug('Received activity from GUI'); - sendDataToPython(message).catch(session.end).done(); - }, - - 'query': function actionQuery(session, message) { - logger.debug('Received query from GUI'); - sendDataToPython(message).then(session.send, session.end).done(); - }, - - 'python_exec': function actionPythonExec(session, message) { - logger.debug('Received python_exec from GUI'); - sendDataToPython(message).then(session.send, session.end).done(); - }, - - 'python_push': function actionPythonPush(session, message) { - logger.debug('Received python_push from GUI'); - sendDataToPython(message).then(session.send, session.end).done(); - }, - - 'python_stop': function actionPythonStop(session, message) { - logger.debug('Received python_stop from GUI'); - sendDataToPython(message).then(session.send, session.end).done(); - }, - - 'hint': function actionHint(session, message) { - logger.debug('Received hint from GUI'); - sendDataToPython(message).then(session.send, session.end).done(); - }, - - 'test': function actionTest(session, message) { - logger.debug('Received test from GUI'); - sendDataToPython(message).then(session.send, session.end).done(); - }, - - 'get_problem': function actionTest(session, message) { - logger.debug('Received get_problem from GUI'); - sendDataToPython(message).then(session.send, session.end).done(); - }, - - 'settings': function actionSettings(session, message) { - logger.debug('Received settings from GUI'); - sendDataToPython(message).then(session.send, session.end).done(); - } + // actions to use default handling should define truthy values that are not functions + // (this is to filter out unnecessary traffic before it hits Python) + 'activity': true, + 'query': true, + 'python_exec': true, + 'python_push': true, + 'python_stop': true, + 'hint': true, + 'test': true, + 'get_problem': true, + 'settings': true }; server.on('connection', function (socket) { @@ -218,7 +169,7 @@ server.on('connection', function (socket) { logger.debug('GUI socket closed: ' + reason); if (session.sid !== null) { if (sessions[session.sid] === session) delete sessions[session.sid]; - sendDataToPython({'type': 'unregister', 'sid': session.sid}); + sendDataToPython({'type': 'unregister', 'sid': session.sid}).done(); } }); @@ -291,7 +242,15 @@ server.on('connection', function (socket) { } try { - handler(session, m); + if (typeof handler === 'function') { + // special case processing + handler(session, m); + } + else { + // default processing: just proxy it through to Python +// logger.debug((session.sid || '[no session]') + ': Received ' + action + ' from GUI'); + sendDataToPython(m).then(session.send, session.end).done(); + } session.lastTID = tid; } catch (e) { @@ -348,7 +307,7 @@ var processPacketFromPython = function processPacketFromPythonFunc(packetString) key = m.tid + ':' + m.sid; resolver = pythonPromises[key]; if (!resolver) { - key = '' + m.tid + key = '' + m.tid; resolver = pythonPromises[key]; } } @@ -395,7 +354,7 @@ var processPacketFromPython = function processPacketFromPythonFunc(packetString) // this is internal function to python connection handler var sendPacketToPython = function sendPacketToPythonFunc(packet) { if (pythonSaturated || (pythonClient === null)) return false; - logger.debug('Attempting to send a packet to Python: ' + packet); + logger.debug('Sending to Python: ' + packet); try { pythonSaturated = !pythonClient.write(packet, 'utf8'); return true; -- cgit v1.2.1