summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleš Smodiš <aless@guru.si>2015-10-04 11:43:48 +0200
committerAleš Smodiš <aless@guru.si>2015-10-04 11:43:48 +0200
commit8c61a1980c973c649a2d9b3b9da67f2a680f4139 (patch)
treebdae08ae589db5c335b140e65e8d0c4475cdefe2
parent089d5ff860dfca2c1eae483ed0b855661fd95235 (diff)
Improved exception tolerance, added logging to a file, removed old code, simplified handling of common requests.
-rw-r--r--web/main.js121
1 files changed, 40 insertions, 81 deletions
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;