# HG changeset patch # User John "Elwin" Edwards # Date 1339204307 25200 # Node ID f7116eb3f791398406d43119014a76e9b70d3268 # Parent e8ac0e3d26143ec61decee6ba1a352079d583fb6 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. diff -r e8ac0e3d2614 -r f7116eb3f791 rlgwebd.js --- 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] */