Mercurial > hg > rlgwebd
changeset 40:f7116eb3f791
rlgwebd.js: refactor some game-starting code.
Separate things like checking for games in progress, starting a new
game, and figuring out where the lockfile and ttyrec should go. This
allows e.g. the games-in-progress check to be used to create status
messages. It also keeps the argument list for the TermSession
constructor to a sensible size.
author | John "Elwin" Edwards <elwin@sdf.org> |
---|---|
date | Fri, 08 Jun 2012 18:11:47 -0700 |
parents | e8ac0e3d2614 |
children | ea3b7775009d |
files | rlgwebd.js |
diffstat | 1 files changed, 42 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/rlgwebd.js Thu Jun 07 15:43:06 2012 -0700 +++ b/rlgwebd.js Fri Jun 08 18:11:47 2012 -0700 @@ -54,7 +54,8 @@ * adds itself to the sessions dict. It currently assumes the user has * been authenticated. */ -function TermSession(game, user, files, dims) { +/* TODO take a callback, or emit success/err events. */ +function TermSession(game, user, dims) { /* First make sure starting the game will work. */ if (game in games) { this.game = games[game]; @@ -63,7 +64,7 @@ // TODO: throw an exception instead return null; } - this.player = user; + this.player = String(user); /* This order seems to best avoid race conditions... */ this.alive = false; this.sessid = randkey(2); @@ -97,10 +98,15 @@ var ss = this; this.alive = true; this.data = []; - this.lock = files[0]; - fs.writeFile(this.lock, this.child.pid.toString() + '\n' + this.w + '\n' + - this.h + '\n', "utf8"); - this.record = fs.createWriteStream(files[1], { mode: 0664 }); + /* Set up the lockfile and ttyrec */ + var ts = timestamp(); + var progressdir = "/dgldir/inprogress-" + this.game.uname; + this.lock = path.join(progressdir, this.player + ":node:" + ts + ".ttyrec"); + var lmsg = this.child.pid.toString() + '\n' + this.w + '\n' + this.h + '\n'; + fs.writeFile(this.lock, lmsg, "utf8"); + var ttyrec = path.join("/dgldir/ttyrec", this.player, this.game.uname, + ts + ".ttyrec"); + this.record = fs.createWriteStream(ttyrec, { mode: 0664 }); /* END setup */ function ttyrec_chunk(buf) { var ts = new Date(); @@ -219,6 +225,27 @@ }; } +function checkprogress(user, game, callback, args) { + var progressdir = "/dgldir/inprogress-" + game.uname; + fs.readdir(progressdir, function(err, files) { + if (err) { + args.unshift(err, null); + callback.apply(null, args); + return; + } + var fre = RegExp("^" + user + ":"); + for (var i = 0; i < files.length; i++) { + if (files[i].match(fre)) { + args.shift(null, files[i]); + callback.apply(null, args); + return; + } + } + args.shift(null, false); + callback.apply(null, args); + }); +} + /* A few utility functions */ function timestamp() { dd = new Date(); @@ -374,28 +401,16 @@ tslog("Request for nonexistant game \"%s\"", gname); return; } - // check for an existing game - var progressdir = "/dgldir/inprogress-" + games[gname].uname; - fs.readdir(progressdir, function(err, files) { - if (!err) { - var fre = RegExp("^" + username + ":"); - for (var i = 0; i < files.length; i++) { - if (files[i].match(fre)) { - sendError(res, 4, null); - tslog("%s is already playing %s", username, gname); - return; - } - } + // A callback to pass to the game-in-progress checker. + var launch = function(err, fname) { + if (fname) { + sendError(res, 4, null); + tslog("%s is already playing %s", username, gname); + return; } // Game starting has been approved. - var ts = timestamp(); - var lockfile = path.join(progressdir, username + ":node:" + ts + ".ttyrec"); - var ttyrec = path.join("/dgldir/ttyrec", username, gname, ts + ".ttyrec"); - var nsession = new TermSession(gname, username, [lockfile, ttyrec], dims); + var nsession = new TermSession(gname, username, dims); if (nsession) { - /* Technically there's a race condition for the "lock"file, but since - * it requires the user deliberately starting two games at similar times, - * it's not too serious. We can't get O_EXCL in Node anyway. */ res.writeHead(200, {'Content-Type': 'application/json'}); var reply = {"t": "l", "id": nsession.sessid, "w": nsession.w, "h": nsession.h}; @@ -408,7 +423,8 @@ sendError(res, 5, "Failed to open TTY"); tslog("Unable to allocate TTY for %s", gname); } - }); + } + checkprogress(username, games[gname], launch, []); } /* Sets things up for a new user, like dgamelaunch's commands[register] */