(function () { var activityQueue = []; var send = function (service, json) { if (json instanceof Object) json = codeq.jsonize(json); return Q.Promise(function (resolve, reject, notify) { $.ajax({ 'type': 'POST', 'url': codeq.urlPrefix + service, 'accepts': 'application/json', 'contentType': 'application/json; charset=UTF-8', // type of our request 'data': json, 'processData': false, // don't process outgoing data 'dataType': 'json', // expected type of the response 'timeout': 60000, // one minute 'error': function sendErrorHandler(jqXHR, textStatus, errorThrown) { reject(new Error(errorThrown || textStatus)); }, 'success': function sendSuccessHandler(data, textStatus, jqXHR) { resolve(data); } }); }); }; var sendCount = 0, resolveWaiters = [], currentSolution = null, resolveActivity = function () { var i; // signal everyone that the queue is flushed for (i = 0; i < resolveWaiters.length; i++) { try { resolveWaiters[i][0](); } catch (e) {} } resolveWaiters.length = 0; }, sendActivityInternal = function () { var trace; // send max. 100 activities, do not be excessive if (activityQueue.length == 0) return resolveActivity(); if (activityQueue.length > 100) { sendCount = 100; trace = activityQueue.slice(0, 100); } else { sendCount = activityQueue.length; trace = activityQueue; } send('trace', {'trace': trace, 'solution': currentSolution}).then( function sendActivitySuccess() { activityQueue.splice(0, sendCount); if (activityQueue.length > 0) sendActivityInternal(); else resolveActivity(); }, function sendActivityFailure() { Q.delay(500).then(sendActivityInternal).done(); } ).done(); }; codeq.comms = { sendActivity: function commsSendActivity (json, solution) { return Q.Promise(function (resolve, reject, notify) { var triggerSending = activityQueue.length == 0, i, js; if (json instanceof Array) { for (i = 0; i < json.length; i++) { js = json[i]; js['sid'] = codeq.sid; activityQueue.push(js); } } else { json['sid'] = codeq.sid; activityQueue.push(json); } if (solution) currentSolution = solution; resolveWaiters.push([resolve, reject]); if (triggerSending) { setTimeout(sendActivityInternal, 0); // async trigger: see if you can collect some more payload } }); }, sendQuery: function commsSendQuery (json) { var thisTrace; json['sid'] = codeq.sid; if (activityQueue.length > 0) { thisTrace = json['trace']; if (thisTrace instanceof Array) { activityQueue.splice(0, 0, 0, 0); // add two zeros in front, they will form the first two parameters to the next splice() thisTrace.splice.apply(thisTrace, activityQueue); } else { json['trace'] = activityQueue.slice(); } activityQueue.length = 0; if (currentSolution) json['solution'] = currentSolution; } return send('query', json); }, getProblem: function commsGetProblem (language, problem_group, problem) { return send('get_problem', { 'sid': codeq.sid, 'language': language, 'problem_group': problem_group, 'problem': problem }); } }; })();