From fac8e72861abe5c2b29ff9b84edc92e528a2fca3 Mon Sep 17 00:00:00 2001 From: Beaudan Date: Mon, 4 Feb 2019 11:14:31 +1100 Subject: [PATCH] Added queue manager to properly fix the race condition bug and reset the changes I made in other commit --- app/sql.js | 8 ++------ background.html | 1 + js/modules/data.js | 2 +- js/queue_manager.js | 28 ++++++++++++++++++++++++++++ libtextsecure/http-resources.js | 18 +++++++++++------- 5 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 js/queue_manager.js diff --git a/app/sql.js b/app/sql.js index 95aa17e82..b64c4feac 100644 --- a/app/sql.js +++ b/app/sql.js @@ -1534,22 +1534,18 @@ async function saveMessage(data, { forceSave } = {}) { return toCreate.id; } -async function saveSeenMessageHashes(incomingHashes) { +async function saveSeenMessageHashes(arrayOfHashes) { let promise; - const hashList = incomingHashes.map(h => h.hash); - const dupHashes = await getSeenMessagesByHashList(hashList); - const newHashes = incomingHashes.filter(h => !dupHashes.includes(h.hash)); db.serialize(() => { promise = Promise.all([ db.run('BEGIN TRANSACTION;'), - ...map(newHashes, hashData => saveSeenMessageHash(hashData)), + ...map(arrayOfHashes, hashData => saveSeenMessageHash(hashData)), db.run('COMMIT TRANSACTION;'), ]); }); await promise; - return newHashes; } async function saveSeenMessageHash(data) { diff --git a/background.html b/background.html index f2a11cda3..7fa85684e 100644 --- a/background.html +++ b/background.html @@ -723,6 +723,7 @@ + diff --git a/js/modules/data.js b/js/modules/data.js index 622750aff..e850c723d 100644 --- a/js/modules/data.js +++ b/js/modules/data.js @@ -788,7 +788,7 @@ async function cleanSeenMessages() { } async function saveSeenMessageHashes(data) { - return channels.saveSeenMessageHashes(_cleanData(data)); + await channels.saveSeenMessageHashes(_cleanData(data)); } async function saveSeenMessageHash(data) { diff --git a/js/queue_manager.js b/js/queue_manager.js new file mode 100644 index 000000000..7202c83dc --- /dev/null +++ b/js/queue_manager.js @@ -0,0 +1,28 @@ +/* eslint-disable more/no-then */ + +// eslint-disable-next-line func-names +(function() { + 'use strict' + + class JobQueue { + constructor() { + this.pending = Promise.resolve(); + } + + add(job) { + const previous = this.pending || Promise.resolve(); + this.pending = previous.then(job, job); + const current = this.pending; + + current.then(() => { + if (this.pending === current) { + delete this.pending; + } + }); + + return current; + } + } + + window.JobQueue = JobQueue; +})(); diff --git a/libtextsecure/http-resources.js b/libtextsecure/http-resources.js index 995655181..4ac3ee38c 100644 --- a/libtextsecure/http-resources.js +++ b/libtextsecure/http-resources.js @@ -45,15 +45,16 @@ const filterIncomingMessages = async function filterIncomingMessages( messages ) { - const incomingHashes = messages.map(m => ({ + const incomingHashes = messages.map(m => m.hash); + const dupHashes = await window.Signal.Data.getSeenMessagesByHashList( + incomingHashes + ); + const newMessages = messages.filter(m => !dupHashes.includes(m.hash)); + const newHashes = newMessages.map(m => ({ expiresAt: m.expiration, hash: m.hash, })); - let newHashes = await window.Signal.Data.saveSeenMessageHashes( - incomingHashes - ); - newHashes = newHashes.map(h => h.hash); - const newMessages = messages.filter(m => newHashes.includes(m.hash)); + await window.Signal.Data.saveSeenMessageHashes(newHashes); return newMessages; }; @@ -64,9 +65,12 @@ handleRequest = request => request.respond(404, 'Not found'); } let connected = false; + const jobQueue = new window.JobQueue(); const processMessages = async messages => { - const newMessages = await filterIncomingMessages(messages); + const newMessages = await jobQueue.add( + () => filterIncomingMessages(messages) + ); newMessages.forEach(async message => { const { data } = message; this.handleMessage(data);