RLGWebD: Clean up code related to session timestamps.
TermSessions now store the timestamp of the latest data. This removes the need to use fstat() to calculate idle times. The reaper() function is removed. It may be useful to find another way to remove old login keys.
This commit is contained in:
parent
c7fc6418ff
commit
abb4ba8f31
1 changed files with 14 additions and 86 deletions
100
rlgwebd.js
100
rlgwebd.js
|
|
@ -19,7 +19,6 @@ var httpPort = 8080;
|
|||
var chrootDir = "/var/dgl/";
|
||||
var dropToUser = "rodney";
|
||||
var serveStaticRoot = "/var/www/"; // inside the chroot
|
||||
var playtimeout = 3600000; // Idle time before games are autosaved, in ms
|
||||
|
||||
/* Data on the games available. */
|
||||
var games = {
|
||||
|
|
@ -122,7 +121,8 @@ function TermSession(game, lkey, dims, handlers) {
|
|||
this.emit('open', true, this.game.uname, this.pname);
|
||||
gamemux.emit('begin', this.game.uname, this.pname);
|
||||
/* Set up the lockfile and ttyrec */
|
||||
var ts = timestamp();
|
||||
this.lasttime = new Date();
|
||||
var ts = timestamp(this.lasttime);
|
||||
var progressdir = path.join("/dgldir/inprogress", this.game.uname);
|
||||
this.lock = path.join(progressdir, this.pname + ":node:" + ts + ".ttyrec");
|
||||
var lmsg = this.term.pid.toString() + '\n' + this.h + '\n' + this.w + '\n';
|
||||
|
|
@ -134,15 +134,14 @@ function TermSession(game, lkey, dims, handlers) {
|
|||
* with a complete screen. */
|
||||
this.framebuf = new Buffer(1024);
|
||||
this.frameoff = 0;
|
||||
logins[lkey].sessions.push(this.game.uname + "/" + this.pname);
|
||||
/* END setup */
|
||||
function ttyrec_chunk(datastr) {
|
||||
var ts = new Date();
|
||||
ss.lasttime = new Date();
|
||||
var buf = new Buffer(datastr);
|
||||
var chunk = new Buffer(buf.length + 12);
|
||||
/* TTYREC headers */
|
||||
chunk.writeUInt32LE(Math.floor(ts.getTime() / 1000), 0);
|
||||
chunk.writeUInt32LE(1000 * (ts.getTime() % 1000), 4);
|
||||
chunk.writeUInt32LE(Math.floor(ss.lasttime.getTime() / 1000), 0);
|
||||
chunk.writeUInt32LE(1000 * (ss.lasttime.getTime() % 1000), 4);
|
||||
chunk.writeUInt32LE(buf.length, 8);
|
||||
buf.copy(chunk, 12);
|
||||
ss.record.write(chunk);
|
||||
|
|
@ -373,8 +372,10 @@ function playerstatus(user, callback) {
|
|||
}
|
||||
|
||||
/* A few utility functions */
|
||||
function timestamp() {
|
||||
dd = new Date();
|
||||
function timestamp(dd) {
|
||||
if (!(dd instanceof Date)) {
|
||||
dd = new Date();
|
||||
}
|
||||
sd = dd.toISOString();
|
||||
sd = sd.slice(0, sd.indexOf("."));
|
||||
return sd.replace("T", ".");
|
||||
|
|
@ -457,47 +458,6 @@ function getMsgWS(msgObj) {
|
|||
return getMsg(msgObj.utf8Data);
|
||||
}
|
||||
|
||||
/* FIXME sessid removal */
|
||||
function reaper() {
|
||||
return; // TODO figure out if this function is useful
|
||||
var now = new Date();
|
||||
function reapcheck(session) {
|
||||
fs.fstat(session.record.fd, function (err, stats) {
|
||||
if (!err && now - stats.mtime > playtimeout) {
|
||||
tslog("Reaping session %s", session.sessid);
|
||||
/* Dissociate it with its login name. */
|
||||
var sn = logins[session.key].sessions.indexOf(session.sessid);
|
||||
if (sn >= 0) {
|
||||
logins[session.key].sessions.splice(sn, 1);
|
||||
}
|
||||
/* Shut it down. */
|
||||
session.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
for (var sessid in sessions) {
|
||||
reapcheck(sessions[sessid]);
|
||||
}
|
||||
for (var lkey in logins) {
|
||||
if (logins[lkey].sessions.length > 0) {
|
||||
/* Check for games that have terminated normally, and remove them. */
|
||||
var expired = [];
|
||||
var targarray = logins[lkey].sessions;
|
||||
/* Let's not find out what happens if you modify an array
|
||||
* you're iterating through. */
|
||||
for (var i = 0; i < targarray.length; i++) {
|
||||
if (!(targarray[i] in sessions))
|
||||
expired.push(targarray[i]);
|
||||
}
|
||||
if (expired.length > 0) {
|
||||
for (var j = 0; j < expired.length; j++) {
|
||||
targarray.splice(targarray.indexOf(expired[j]), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function login(req, res, formdata) {
|
||||
if (!allowlogin) {
|
||||
sendError(res, 6, null, false);
|
||||
|
|
@ -528,7 +488,7 @@ function login(req, res, formdata) {
|
|||
var lkey = randkey(2);
|
||||
while (lkey in logins)
|
||||
lkey = randkey(2);
|
||||
logins[lkey] = {"name": username, "ts": new Date(), "sessions": []};
|
||||
logins[lkey] = {"name": username, "ts": new Date()};
|
||||
res.writeHead(200, {'Content-Type': 'application/json'});
|
||||
var reply = {"t": "l", "k": lkey, "u": username};
|
||||
res.write(JSON.stringify(reply));
|
||||
|
|
@ -579,7 +539,7 @@ function register(req, res, formdata) {
|
|||
var lkey = randkey(2);
|
||||
while (lkey in logins)
|
||||
lkey = randkey(2);
|
||||
logins[lkey] = {"name": uname, "ts": new Date(), "sessions": []};
|
||||
logins[lkey] = {"name": uname, "ts": new Date()};
|
||||
var reply = {"t": "r", "k": lkey, "u": uname};
|
||||
res.writeHead(200, {'Content-Type': 'application/json'});
|
||||
res.write(JSON.stringify(reply));
|
||||
|
|
@ -732,54 +692,23 @@ function serveStatic(req, res, fname) {
|
|||
return;
|
||||
}
|
||||
|
||||
/* TODO simplify by storing timestamps instead of callin stat() */
|
||||
/* Currently, this doesn't do anything blocking, but keep the callback */
|
||||
function getStatus(callback) {
|
||||
var now = new Date();
|
||||
var statusinfo = {"s": allowlogin, "g": []};
|
||||
function idleset(n, idletime) {
|
||||
if (n >= 0 && n < statusinfo.g.length) {
|
||||
statusinfo.g[n].i = idletime;
|
||||
}
|
||||
for (var j = 0; j < statusinfo.g.length; j++) {
|
||||
if (!("i" in statusinfo.g[j]))
|
||||
return;
|
||||
}
|
||||
callback(statusinfo);
|
||||
}
|
||||
for (var tag in sessions) {
|
||||
var gamedesc = {};
|
||||
gamedesc["tag"] = tag;
|
||||
gamedesc["p"] = sessions[tag].pname;
|
||||
gamedesc["g"] = sessions[tag].game.uname;
|
||||
gamedesc["i"] = now - sessions[tag].lasttime;
|
||||
statusinfo["g"].push(gamedesc);
|
||||
}
|
||||
statusinfo["dgl"] = [];
|
||||
for (var tag in dglgames) {
|
||||
statusinfo["dgl"].push(tag);
|
||||
}
|
||||
if (statusinfo.g.length == 0) {
|
||||
callback(statusinfo);
|
||||
return;
|
||||
}
|
||||
function makecallback(i) {
|
||||
return function (err, stats) {
|
||||
if (err)
|
||||
idleset(i, null);
|
||||
else
|
||||
idleset(i, now - stats.mtime);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < statusinfo.g.length; i++) {
|
||||
/* fd sometimes isn't a number, presumably when the file isn't open yet. */
|
||||
/* FIXME sessid -> tag */
|
||||
var tag = statusinfo.g[i].tag;
|
||||
if (tag in sessions && typeof(sessions[tag].record.fd) == 'number') {
|
||||
fs.fstat(sessions[tag].record.fd, makecallback(i));
|
||||
}
|
||||
else {
|
||||
idleset(i, null);
|
||||
}
|
||||
}
|
||||
callback(statusinfo);
|
||||
}
|
||||
|
||||
function statusmsg(req, res) {
|
||||
|
|
@ -1134,7 +1063,6 @@ ctlServer.listen(ctlsocket, function () {
|
|||
httpServer = http.createServer(webHandler);
|
||||
httpServer.listen(httpPort);
|
||||
tslog('rlgwebd running on port %d', httpPort);
|
||||
setInterval(reaper, playtimeout / 4);
|
||||
wsServer = new WebSocketServer({"httpServer": httpServer});
|
||||
wsServer.on("request", wsHandler);
|
||||
tslog('WebSockets are online');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue