submit related updates in series with proper modified times

This commit is contained in:
Jesse D. McDonald 2020-04-28 23:15:04 -05:00
parent 63d02e8ad4
commit bac6305cb7
1 changed files with 107 additions and 24 deletions

View File

@ -436,6 +436,112 @@ $(function (){
putMeta({ board: moves }); putMeta({ board: moves });
} }
let noticeBox = null;
function openNoticeBox(content) {
if (noticeBox) {
noticeBox.setContent(content);
noticeBox.open();
} else {
noticeBox = new jBox('Notice', {
autoClose: false,
closeOnEsc: false,
closeOnClick: false,
content: content,
delayClose: 2000,
delayOpen: 100,
onClose() {
if (noticeBox === this) {
noticeBox = null;
}
},
onCloseComplete() {
this.destroy();
},
});
}
}
const updateQueue = {
head: 0, /* next item to be sent */
tail: 0, /* ID to assign to the next update added to the queue */
lastGameId: null,
lastModified: null,
newModified: 0,
sending: false,
add(gameId, data, modified) {
const wasEmpty = this.head === this.tail;
data = Object.assign({}, data, { modified });
this[this.tail] = { gameId, data, modified };
this.tail += 1;
if (!this.sending) {
openNoticeBox('Saving...');
this.sending = true;
this.sendNext();
}
},
sendNext() {
const queue = this;
if (queue.head === queue.tail) {
return;
}
const update = queue[queue.head];
delete queue[queue.head];
queue.head += 1;
if (update.gameId === queue.lastGameId && update.modified === queue.lastModified) {
update.data.modified = queue.newModified;
}
IO.sendUpdate(update.gameId, update.data).then((response) => {
queue.lastGameId = update.gameId;
if (response && response.data && 'modified' in response.data) {
/*
* If we queued two or more updates with the same .modified (thus
* based on the same server data), send the next update with the
* new .modified assigned by the server as a result of this update.
*/
queue.lastModified = update.modified; /* original, not adjusted */
queue.newModified = response.data.modified;
} else {
queue.lastModified = null;
queue.newModified = 0;
}
if (queue.head === queue.tail) {
queue.sending = false;
/* close the Saving... notice*/
noticeBox.close({ ignoreDelay: true });
} else {
queue.sendNext();
}
}).catch((err) => {
openNoticeBox('Failed to send update to server.');
noticeBox.close();
debug('update error', err);
/* additional updates are unlikely to succeed, so empty the queue */
while (queue.head < queue.tail) {
delete queue[queue.head];
queue.head += 1;
}
queue.sending = false;
/* force a reset back to the latest server data */
if (update.gameId === $('#cb_board').data('gameId')) {
switchGameId(update.gameId, true);
}
});
},
};
function putMeta(extra) { function putMeta(extra) {
const gameId = $('#cb_board').data('gameId'); const gameId = $('#cb_board').data('gameId');
const lightName = $('#cb_light_name').val(); const lightName = $('#cb_light_name').val();
@ -462,30 +568,7 @@ $(function (){
Object.assign(meta, extra); Object.assign(meta, extra);
} }
const noticeBox = new jBox('Notice', { updateQueue.add(gameId, meta, $('#cb_board').data('modified'));
content: 'Saving...',
autoClose: false,
delayOpen: 200,
delayClose: 2000,
onCloseComplete() { this.destroy(); },
});
const modified = meta.modified = $('#cb_board').data('modified');
IO.sendUpdate(gameId, meta).then((response) => {
noticeBox.close({ ignoreDelay: true });
if (response && response.data && Number.isInteger(response.data.modified)) {
if (response.data.modified > modified) {
$('#cb_board').data('modified', response.data.modified);
}
}
}).catch((err) => {
noticeBox.setContent('Failed to send update to server.');
noticeBox.close();
debug('update error', err);
/* force a reset back to the latest server data */
switchGameId(gameId, true);
});
} }
function switchGameId(newId, force) { function switchGameId(newId, force) {