summaryrefslogtreecommitdiff
path: root/js/codeq/comms.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/codeq/comms.js')
-rw-r--r--js/codeq/comms.js107
1 files changed, 62 insertions, 45 deletions
diff --git a/js/codeq/comms.js b/js/codeq/comms.js
index eece7e7..cff1015 100644
--- a/js/codeq/comms.js
+++ b/js/codeq/comms.js
@@ -1,7 +1,5 @@
(function () {
- var activityQueue = [];
-
var send = function (service, json) {
if (json instanceof Object) json = codeq.jsonize(json);
return Q.Promise(function (resolve, reject, notify) {
@@ -24,37 +22,42 @@
});
};
- var sendCount = 0,
- resolveWaiters = [],
- currentSolution = null,
- resolveActivity = function () {
+ var activities = {}, // keyed by problem_id: activity info waiting to be sent to the server
+ activityKeys = [], // the keys to activities dictionary
+ resolveActivity = function (promiseResolvers) {
var i;
// signal everyone that the queue is flushed
- for (i = 0; i < resolveWaiters.length; i++) {
+ for (i = 0; i < promiseResolvers.length; i++) {
try {
- resolveWaiters[i][0]();
+ promiseResolvers[i][0]();
}
catch (e) {}
}
- resolveWaiters.length = 0;
+ promiseResolvers.length = 0;
},
sendActivityInternal = function () {
- var trace;
+ var activityKey, activityDescriptor, trace, sendCount;
// send max. 100 activities, do not be excessive
- if (activityQueue.length == 0) return resolveActivity();
- if (activityQueue.length > 100) {
+ if (activityKeys.length == 0) return;
+ activityKey = activityKeys[0];
+ activityDescriptor = activities[activityKey];
+ trace = activityDescriptor.trace;
+ if (trace.length > 100) {
sendCount = 100;
- trace = activityQueue.slice(0, 100);
+ trace = trace.slice(0, 100);
}
else {
- sendCount = activityQueue.length;
- trace = activityQueue;
+ sendCount = trace.length;
}
- send('trace', {'trace': trace, 'solution': currentSolution}).then(
+ send('activity', {'trace': trace, 'solution': activityDescriptor.solution, 'problem_id': activityDescriptor.problem_id, 'sid': codeq.sid}).then(
function sendActivitySuccess() {
- activityQueue.splice(0, sendCount);
- if (activityQueue.length > 0) sendActivityInternal();
- else resolveActivity();
+ activityDescriptor.trace.splice(0, sendCount);
+ if (activityDescriptor.trace.length > 0) sendActivityInternal();
+ else {
+ delete activities[activityKey];
+ activityKeys.shift();
+ resolveActivity(activityDescriptor.promiseResolvers);
+ }
},
function sendActivityFailure() {
Q.delay(500).then(sendActivityInternal).done();
@@ -63,45 +66,59 @@
};
codeq.comms = {
- sendActivity: function commsSendActivity (json, solution) {
+ sendActivity: function commsSendActivity (trace, solution, problem_id) {
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);
+ var triggerSending = activityKeys.length == 0,
+ activityDescriptor = activities[problem_id],
+ problemTrace, promiseResolvers, i;
+ if (!activityDescriptor) {
+ problemTrace = [];
+ promiseResolvers = [];
+ activityDescriptor = {
+ 'problem_id': problem_id,
+ 'trace': problemTrace,
+ 'solution': solution,
+ 'promiseResolvers': promiseResolvers
+ };
+ activities[problem_id] = activityDescriptor;
+ activityKeys.push(problem_id);
+ }
+ else {
+ problemTrace = activityDescriptor.trace;
+ promiseResolvers = activityDescriptor.promiseResolvers;
+ if (solution) activityDescriptor.solution = solution;
+ }
+ if (trace instanceof Array) {
+ for (i = 0; i < trace.length; i++) {
+ problemTrace.push(trace[i]);
}
}
else {
- json['sid'] = codeq.sid;
- activityQueue.push(json);
+ problemTrace.push(trace);
}
- if (solution) currentSolution = solution;
- resolveWaiters.push([resolve, reject]);
+ promiseResolvers.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();
+ sendQuery: function commsSendQuery (query, problem_id) {
+ var existingActivity = activities[problem_id],
+ tmp;
+ query['sid'] = codeq.sid;
+ if (existingActivity) {
+ tmp = query['trace'];
+ if (tmp) {
+ // the trace will be sent separately, so it will be in the proper order
+ tmp.splice(0, 0, existingActivity.trace.length, 0); // add two parameters in front, they will form the first two parameters to the following splice() invocation
+ existingActivity.trace.splice.apply(existingActivity.trace, tmp);
+ delete query['trace'];
}
- activityQueue.length = 0;
- if (currentSolution) json['solution'] = currentSolution;
+ tmp = query['program'];
+ if (tmp) existingActivity.solution = tmp;
}
- return send('query', json);
+ return send('query', query);
},
getProblem: function commsGetProblem (language, problem_group, problem) {