Skip to content

Commit

Permalink
Merge branch master into prod to get PRs #447, #453, #443, #454, #455
Browse files Browse the repository at this point in the history
…and #458
  • Loading branch information
cpcallen authored Mar 17, 2021
2 parents dcb61a3 + cd7ceaa commit 8c420f4
Show file tree
Hide file tree
Showing 36 changed files with 1,483 additions and 1,668 deletions.
45 changes: 30 additions & 15 deletions connect/connectServer
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ const DEFAULT_CFG = {
var Queue = function (id) {
// Save 'this' for closures below.
var thisQueue = this;
/**
* ID of this queue in queueList.
*/
this.id = id;
/**
* Time that this queue was pinged by a user. Abandoned queues are deleted.
*/
Expand Down Expand Up @@ -91,12 +95,7 @@ var Queue = function (id) {
*/
this.client = new net.Socket();

this.client.on('close', function() {
if (queueList[id]) {
delete queueList[id];
console.log('Code City closed session ' + id);
}
});
this.client.on('close', this.destroy.bind(this, 'Code City closed session'));

this.client.on('error', function(error) {
console.log('TCP error for session ' + id, error);
Expand Down Expand Up @@ -155,6 +154,18 @@ var Queue = function (id) {
this.client.connect(CFG.remotePort, CFG.remoteHost);
};

/**
* Close this queue and deregister it.
* @param {string} msg Console message to print (with ID appended).
*/
Queue.prototype.destroy = function(msg) {
if (queueList[this.id]) {
delete queueList[this.id];
}
this.client.end();
console.log(msg + ' ' + this.id);
};

/**
* Load a file from disk, add substitutions, and serve to the web.
* @param {!Object} response HTTP server response object.
Expand Down Expand Up @@ -278,7 +289,7 @@ function handleRequest(request, response) {
try {
var receivedJson = JSON.parse(requestBody);
if (!receivedJson['q']) {
throw 'no queue';
throw Error('No queue');
}
} catch (e) {
console.error('Illegal JSON');
Expand All @@ -300,6 +311,7 @@ function ping(receivedJson, response) {
var ackMemoNum = receivedJson['ackMemoNum'];
var cmdNum = receivedJson['cmdNum'];
var cmds = receivedJson['cmds'];
var logout = receivedJson['logout'];

var queue = queueList[q];
if (!queue) {
Expand Down Expand Up @@ -343,11 +355,16 @@ function ping(receivedJson, response) {
var ackCmdNextPing = false;
}

// Wait a fifth of a second for each command,
// but don't wait for more than a second.
var delay = Math.min(delay, 1000);
var replyFunc = pong.bind(null, queue, response, ackCmdNextPing);
setTimeout(replyFunc, delay);
if (logout) {
pong(queue, response, ackCmdNextPing);
queue.destroy('Client disconnected');
} else {
// Wait a fifth of a second for each command,
// but don't wait for more than a second.
var delay = Math.min(delay, 1000);
var replyFunc = pong.bind(null, queue, response, ackCmdNextPing);
setTimeout(replyFunc, delay);
}
}

function pong(queue, response, ackCmdNextPing) {
Expand Down Expand Up @@ -396,9 +413,7 @@ function cleanup() {
for (var id in queueList) {
var queue = queueList[id];
if (queue.lastPingTime < bestBefore) {
queue.client.end();
delete queueList[id];
console.log('Timeout of session ' + id);
queue.destroy('Timeout of session');
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions core/core_10_base.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ $.system.onStartup = function onStartup() {
* listening sockets, etc.)
*/
// Listen on various sockets.
try {$.system.connectionListen(7777, $.servers.telnet.connection);} catch(e) {}
try {$.system.connectionListen(7780, $.servers.http.connection);} catch(e) {}
try {$.system.connectionListen(7777, $.servers.telnet.connection, 100);} catch(e) {}
try {$.system.connectionListen(7780, $.servers.http.connection, 100);} catch(e) {}
try {$.system.connectionListen(9999, $.servers.eval.connection);} catch(e) {}
$.system.log('Startup: listeners started.');

Expand Down
228 changes: 195 additions & 33 deletions core/core_11_$.utils.js

Large diffs are not rendered by default.

89 changes: 41 additions & 48 deletions core/core_12_$.utils.code.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,47 @@ $.utils.code.toSource = function toSource(value, opt_seen) {
return String(value);
} else if (proto === Date.prototype) {
return 'new Date(\'' + value.toJSON() + '\')';
} else if (proto === Object.prototype) {
var props = Object.getOwnPropertyNames(value);
var data = [];
for (var i = 0; i < props.length; i++) {
var propName = props[i];
var propValue = value[propName];
try {
var propSource = (typeof propValue === 'function') ?
('function ' + propValue.name + '() { ... }') :
$.utils.code.toSource(propValue, opt_seen);
data[i] = JSON.stringify(propName) + ': ' + propSource;
} catch (e) {
// Recursive data structure. Bail.
data = null;
break;
}
}
if (data) {
var selectorString = '';
/*
var selector = $.Selector.for(value);
if (selector) {
selectorString = ' // ' + selector.toString();
}
*/
if (!data.length) {
return '{}' + selectorString;
}
return '{' + selectorString + '\n' + $.utils.string.prefixLines(data.join(',\n'), ' ') + '\n}';
}
} else if (proto === Array.prototype && Array.isArray(value) &&
value.length <= 100) {
var props = Object.getOwnPropertyNames(value);
var data = [];
for (var i = 0; i < value.length; i++) {
if (props.includes(String(i))) {
var propValue = value[i]
try {
data[i] = $.utils.code.toSource(value[i], opt_seen);
data[i] = (typeof propValue === 'function') ?
('function ' + propValue.name + '() { ... }') :
$.utils.code.toSource(propValue, opt_seen);
} catch (e) {
// Recursive data structure. Bail.
data = null;
Expand All @@ -75,7 +108,10 @@ $.utils.code.toSource = function toSource(value, opt_seen) {
}
}
if (data) {
return '[' + data.join(', ') + ']';
if (!data.length) {
return '[]';
}
return '[\n' + $.utils.string.prefixLines(data.join(',\n'), ' ') + '\n]';
}
} else if (value instanceof Error) {
var constructor;
Expand Down Expand Up @@ -124,7 +160,7 @@ $.utils.code.toSource = function toSource(value, opt_seen) {
// Can't happen.
throw new TypeError('[' + type + ']');
};
Object.setOwnerOf($.utils.code.toSource, $.physicals.Maximilian);
Object.setOwnerOf($.utils.code.toSource, $.physicals.Neil);
$.utils.code.toSource.processingError = false;
$.utils.code.toSourceSafe = function toSourceSafe(value) {
// Same as $.utils.code.toSource, but don't throw any selector errors.
Expand Down Expand Up @@ -365,46 +401,14 @@ $.utils.code.quote = function quote(str) {
return "'" + str.replace(this.quote.singleRE, this.quote.replace) + "'";
}
};
$.utils.code.quote.prototype.constructor = function(str) {
// Convert a string into a string literal. We use single or double
// quotes depending on which occurs less frequently in the string to
// be escaped (prefering single quotes if it's a tie). Strictly
// speaking we only need to escape backslash, \r, \n, \u2028 (line
// separator), \u2029 (paragraph separator) and whichever quote
// character we're using, but for output readability we escape all the
// control characters.
//
// TODO(cpcallen): Consider using optimised algorithm from Node.js's
// util.format (see strEscape function in
// https://github.com/nodejs/node/blob/master/lib/util.js).
// @param {string} str The string to convert.
// @return {string} The value s as a eval-able string literal.
if (count(str, "'") > count(str, '"')) { // More 's. Use "s.
return '"' + str.replace(this.quote.doubleRE, this.quote.replace) + '"';
} else { // Equal or more "s. Use 's.
return "'" + str.replace(this.quote.singleRE, this.quote.replace) + "'";
}
};
delete $.utils.code.quote.prototype.constructor.name;
$.utils.code.quote.prototype.constructor.prototype = $.utils.code.quote.prototype;
$.utils.code.quote.prototype.constructor.singleRE = /[\x00-\x1f\\\u2028\u2029']/g;
$.utils.code.quote.prototype.constructor.doubleRE = /[\x00-\x1f\\\u2028\u2029"]/g;
$.utils.code.quote.prototype.constructor.replace = function(c) {
// Replace special characters with their quoted replacements.
// Intended to be used as the second argument to
// String.prototype.replace.
return $.utils.code.quote.replacements[c];
};
$.utils.code.quote.singleRE = $.utils.code.quote.prototype.constructor.singleRE;
$.utils.code.quote.doubleRE = $.utils.code.quote.prototype.constructor.doubleRE;
$.utils.code.quote.singleRE = /[\x00-\x1f\\\u2028\u2029']/g;
$.utils.code.quote.doubleRE = /[\x00-\x1f\\\u2028\u2029"]/g;
$.utils.code.quote.replace = function replace(c) {
// Replace special characters with their quoted replacements.
// Intended to be used as the second argument to
// String.prototype.replace.
return $.utils.code.quote.replacements[c];
};
$.utils.code.quote.replace.prototype = $.utils.code.quote.prototype.constructor.replace.prototype;
delete $.utils.code.quote.replace.prototype.constructor.name;
$.utils.code.quote.replacements = {};
$.utils.code.quote.replacements['\0'] = '\\0';
$.utils.code.quote.replacements['\x01'] = '\\x01';
Expand All @@ -431,22 +435,11 @@ $.utils.code.count = function count(str, searchString) {
// Count non-overlapping occurrences of searchString in str.
return str.split(searchString).length;
};
$.utils.code.count.prototype.constructor = function(str, searchString) {
// Count non-overlapping occurrences of searchString in str.
return str.split(searchString).length;
};
delete $.utils.code.count.prototype.constructor.name;
$.utils.code.count.prototype.constructor.prototype = $.utils.code.count.prototype;
$.utils.code.isIdentifier = function isIdentifier(id) {
return typeof id === 'string' &&
$.utils.code.regexps.identifierExact.test(id) &&
!$.utils.code.regexps.keywordExact.test(id);
};
$.utils.code.isIdentifier.prototype.constructor = function isIdentifier(id) {
return $.utils.code.regexps.identifierExact.matches(id) &&
!$.utils.code.regexps.keywordExact.matches(id);
};
$.utils.code.isIdentifier.prototype.constructor.prototype = $.utils.code.isIdentifier.prototype;
$.utils.code.getGlobal = function getGlobal() {
// Return a pseudo global object.
var global = Object.create(null);
Expand Down
58 changes: 2 additions & 56 deletions core/core_13_$.Selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,6 @@ $.Selector.SpecialPart = function SpecialPart(type) {
this.type = type;
Object.freeze(this);
};
$.Selector.SpecialPart.prototype.constructor = function SpecialPart(type) {
// A SpecialPart is a class for all "special" selector parts (ones
// which do not represent named variables / properties).
this.type = type;
};
$.Selector.SpecialPart.prototype.constructor.prototype = $.Selector.SpecialPart.prototype;
$.Selector.SpecialPart.prototype.toString = function() {
return '{' + this.type + '}';
};
Expand Down Expand Up @@ -405,54 +399,6 @@ $.Selector.parse.tokenize = function tokenize(selector) {
}
return tokens;
};
$.Selector.parse.tokenize.prototype.constructor = function tokenize(selector) {
// Tokenizes a selector string. Throws a SyntaxError if any text is
// found which does not form a valid token.
var REs = {
whitespace: /^\s+/,
'.': /^\./,
id: new RegExp('^' + $.utils.code.regexp.identifier.source),
number: /^\d+/,
'[': /^\[/,
']': /^\]/,
'{': /^\{/,
'}': /^\}/,
'^': /^\^/,
str: new RegExp('^' + $.utils.code.regexps.string.source),
};

var tokens = [];
NEXT_TOKEN: for (var index = 0; index < selector.length; ) {
for (var tokenType in REs) {
if (!REs.hasOwnProperty(tokenType)) continue;
var re = REs[tokenType];
var m = re.exec(selector.slice(index));
if (!m) continue; // No match. Try next regexp.
tokens.push({
type: tokenType,
raw: m[0],
valid: true,
index: index,
});
index += re.lastIndex;
continue NEXT_TOKEN;
}
// No token matched.
throw new SyntaxError('invalid selector ' + selector);
}

// Postprocess token list to get values.
for(var i = 0; i < tokens.length; i++) {
var token = tokens[i];
if (token.type === 'number') {
token.value = Number(token.raw);
} else if (token.type === 'str') {
token.value = $.utils.code.parseString(token.raw);
}
}
return tokens;
};
$.Selector.parse.tokenize.prototype.constructor.prototype = $.Selector.parse.tokenize.prototype;
$.Selector.for = function Selector_for(object) {
/* Return a Selector for object, or undefined if none known.
*/
Expand Down Expand Up @@ -641,7 +587,7 @@ $.utils.Binding.prototype.get = function get(inherited) {
var part = this.part;
if (this.object === null) {
if (!$.utils.code.isIdentifier(part)) {
throw new TypeError('Invalid part');
throw new TypeError('Invalid part');
}
var evalGlobal = eval;
return evalGlobal(part);
Expand All @@ -656,7 +602,7 @@ $.utils.Binding.prototype.get = function get(inherited) {
return undefined;
}
};
Object.setOwnerOf($.utils.Binding.prototype.get, $.physicals.Maximilian);
Object.setOwnerOf($.utils.Binding.prototype.get, $.physicals.Neil);
$.utils.Binding.prototype.isOwner = function isOwner() {
/* Returns true iff the binding is an bject owner binding.
*/
Expand Down
Loading

0 comments on commit 8c420f4

Please sign in to comment.