merge the /game/ and /meta/ GET handlers
This commit is contained in:
parent
012bc7ea09
commit
674b460cbe
118
index.js
118
index.js
|
|
@ -40,28 +40,6 @@ var appendJournal = (function() {
|
|||
};
|
||||
})();
|
||||
|
||||
function logIn(msg){
|
||||
console.log(`in msg:${JSON.stringify(msg)}.........`);
|
||||
}
|
||||
|
||||
function logOut(msg){
|
||||
console.log(`out msg:${JSON.stringify(msg)}.........`);
|
||||
}
|
||||
|
||||
function logPeers() {
|
||||
console.log(`Peers: ${Object.keys(gun._.opt.peers).join(', ')}`);
|
||||
}
|
||||
|
||||
function logData() {
|
||||
console.log(`In Memory: ${JSON.stringify(gun._.graph)}`);
|
||||
}
|
||||
|
||||
//gun._.on('in', logIn);
|
||||
//gun._.on('out', logOut);
|
||||
|
||||
//setInterval(logPeers, 5000); //Log peer list every 5 secs
|
||||
//setInterval(logData, 20000); //Log gun graph every 20 secs
|
||||
|
||||
function logDbError(label) {
|
||||
return function(err) {
|
||||
console.error(label + ':', ((err && err.message) || err));
|
||||
|
|
@ -115,20 +93,6 @@ function pruneEmpty(obj) {
|
|||
return copy;
|
||||
}
|
||||
|
||||
async function logAllMeta() {
|
||||
const db = await dbInit;
|
||||
try {
|
||||
const querySql = `
|
||||
SELECT gameId, lightName, darkName, moves, status, timestamp FROM games ORDER BY timestamp DESC
|
||||
`;
|
||||
for await (const row of db.eachAsync(querySql)) {
|
||||
console.log(JSON.stringify(pruneEmpty(row)));
|
||||
}
|
||||
} catch(err) {
|
||||
logDbError('logAllMeta')(err);
|
||||
}
|
||||
}
|
||||
|
||||
let waitingAnyGame = null;
|
||||
const waitingGames = {};
|
||||
|
||||
|
|
@ -168,8 +132,6 @@ function waitFor(duration) {
|
|||
return new Promise((resolve, reject) => setTimeout(() => { resolve(); }, duration));
|
||||
}
|
||||
|
||||
//logAllMeta();
|
||||
|
||||
function checkString(value, label, dflt) {
|
||||
try {
|
||||
if (arguments.length >= 3 && (value === undefined || value === null)) {
|
||||
|
|
@ -388,18 +350,23 @@ async function getGameHandler(req, res, next) {
|
|||
const gameUpdate = waitForGameUpdate(gameId).then(() => 'update');
|
||||
|
||||
const querySql = `
|
||||
SELECT board, modified FROM games WHERE gameId = $gameId
|
||||
SELECT lightName, darkName, moves, status, timestamp, board, modified FROM games
|
||||
WHERE gameId = $gameId
|
||||
`;
|
||||
const result = await (await dbInit).getAsync(querySql, { $gameId: gameId });
|
||||
|
||||
if (!result) {
|
||||
res.status(404).json({ message: 'unknown game ID' });
|
||||
if (result && (afterTime === undefined || result.modified > afterTime)) {
|
||||
if (req.params.type === 'meta') {
|
||||
delete result.board;
|
||||
} else {
|
||||
result.board = (result.board === '') ? null : JSON.parse(result.board);
|
||||
}
|
||||
res.json(pruneEmpty(result));
|
||||
return;
|
||||
}
|
||||
|
||||
if (afterTime === undefined || result.modified > afterTime) {
|
||||
const parsed = (result.board === '') ? null : JSON.parse(result.board);
|
||||
res.json({ board: parsed, modified: result.modified });
|
||||
if (afterTime === undefined) {
|
||||
res.status(404).json({ message: 'unknown game ID' });
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -413,54 +380,6 @@ async function getGameHandler(req, res, next) {
|
|||
}
|
||||
}
|
||||
|
||||
async function getMetaHandler(req, res, next) {
|
||||
res.set('Cache-Control', 'no-store');
|
||||
try {
|
||||
const gameId = req.params.gameId;
|
||||
const afterTime = req.params.afterTime;
|
||||
|
||||
if (!gameId.match(/^[0-9a-f]{16}$/)) {
|
||||
res.status(400).json({ message: 'malformed game ID' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (afterTime !== undefined && !afterTime.match(/^\d+$/)) {
|
||||
res.status(400).json({ message: 'malformed time' });
|
||||
return;
|
||||
}
|
||||
|
||||
const pollTimeout = waitFor(POLLING_TIMEOUT).then(() => 'timeout').catch(()=>{});
|
||||
|
||||
while (true) {
|
||||
/* Save the async promise _before_ the query so we don't miss any updates while suspended. */
|
||||
const metaUpdate = waitForGameUpdate(gameId).then(() => 'update');
|
||||
|
||||
const querySql = `
|
||||
SELECT lightName, darkName, moves, status, timestamp, modified FROM games
|
||||
WHERE gameId = $gameId
|
||||
`;
|
||||
const result = await (await dbInit).getAsync(querySql, { $gameId: gameId });
|
||||
|
||||
if (!result) {
|
||||
res.status(404).json({ message: 'unknown game ID' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (afterTime === undefined || result.modified > afterTime) {
|
||||
res.json(pruneEmpty(result));
|
||||
return;
|
||||
}
|
||||
|
||||
if (await Promise.race([metaUpdate, pollTimeout]) === 'timeout') {
|
||||
res.status(204).json({ retry: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
internalErrorJson(err, res);
|
||||
}
|
||||
}
|
||||
|
||||
const updateTemplate = {
|
||||
lightName(x) { return typeof x === 'string'; },
|
||||
darkName(x) { return typeof x === 'string'; },
|
||||
|
|
@ -474,22 +393,18 @@ const updateTemplate = {
|
|||
function validateUpdate(body) {
|
||||
try {
|
||||
if (typeof body !== 'object' || 'modified' in body === false) {
|
||||
console.log('invalid type or missing modified property');
|
||||
return null;
|
||||
}
|
||||
|
||||
for (const key in body) {
|
||||
if (key in updateTemplate === false) {
|
||||
console.log('extra key', key);
|
||||
return null;
|
||||
}
|
||||
if (updateTemplate[key](body[key]) === false) {
|
||||
console.log('invalid value', body[key], 'for key', key);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} catch(err) {
|
||||
console.log('exception', err);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -503,8 +418,6 @@ async function postGameHandler(req, res, next) {
|
|||
const gameId = req.params.gameId;
|
||||
const body = validateUpdate(req.body);
|
||||
|
||||
console.log('update for', gameId, 'at time', time, req.body, !body);
|
||||
|
||||
if (!gameId.match(/^[0-9a-f]{16}$/)) {
|
||||
res.status(400).json({ message: 'malformed game ID' });
|
||||
return;
|
||||
|
|
@ -625,12 +538,9 @@ async function postGameHandler(req, res, next) {
|
|||
app.get('/pacosako/api/games/poll/:afterTime', getGameListHandler);
|
||||
app.get('/pacosako/api/games', getGameListHandler);
|
||||
|
||||
app.get('/pacosako/api/game/:gameId/poll/:afterTime', getGameHandler);
|
||||
app.get('/pacosako/api/game/:gameId', getGameHandler);
|
||||
app.post('/pacosako/api/game/:gameId', express.json(), postGameHandler);
|
||||
|
||||
app.get('/pacosako/api/meta/:gameId/poll/:afterTime', getMetaHandler);
|
||||
app.get('/pacosako/api/meta/:gameId', getMetaHandler);
|
||||
app.get('/pacosako/api/:type(game|meta)/:gameId/poll/:afterTime', getGameHandler);
|
||||
app.get('/pacosako/api/:type(game|meta)/:gameId', getGameHandler);
|
||||
app.post('/pacosako/api/:type(game|meta)/:gameId', express.json(), postGameHandler);
|
||||
|
||||
app.use('/pacosako/api', express.static('public'));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue