diff --git a/index.js b/index.js index 053315f..b7c0500 100644 --- a/index.js +++ b/index.js @@ -394,12 +394,34 @@ async function postGameHandler(req, res, next) { /* Now wait for all the queries to finish. */ const result = await transactionP; - if (!result || result.modified !== params.$time) { - res.status(409).json({ message: 'update failed', modified: (result || {}).modified }); - return; - } + if (result && result.modified === params.$time) { + /* Only signal an update if the record was actually changed. No-ops don't count. */ + signalGameUpdate(gameId); + } else { + /* + * If the record exists and all the values (other than .modified) match the + * request, treat this as a successful no-op. This ensures that repeated + * requests for the same update (i.e. retries) do not fail just because the + * modified time was changed. + */ + let same = false; - signalGameUpdate(gameId); + if (result) { + same = true; + for (const key in body) { + /* Use the value from params since e.g. body.board may be adjusted. */ + if (key !== 'modified' && result[key] !== params['$' + key]) { + same = false; + break; + } + } + } + + if (!same) { + res.status(409).json({ message: 'update failed', modified: (result || {}).modified }); + return; + } + } res.json({ success: true, modified: result.modified }); }