From 7addacba38b65b22f3b36c58ee153e4a0c118b1f Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 21 Nov 2019 18:56:37 +0000 Subject: [PATCH 1/2] Always process call events in batches We had a bunch of logic in place to suppress calls if the answer or hangup had already arrived, but we only used it on startup. This extends this logic to happen all the time, which means we'll also do the same suppression if a call happenned while we were offline. --- src/client.js | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/client.js b/src/client.js index 8f2dec601..410b0e78b 100644 --- a/src/client.js +++ b/src/client.js @@ -4635,17 +4635,17 @@ function setupCallEventHandler(client) { // callId: [Candidate] }; - // Maintain a buffer of events before the client has synced for the first time. - // This buffer will be inspected to see if we should send incoming call - // notifications. It needs to be buffered to correctly determine if an - // incoming call has had a matching answer/hangup. + // The sync code always emits one event at a time, so it will patiently + // wait for us to finish processing a call invite before delivering the + // next event, even if that next event is a hangup. We therefore accumulate + // all our call events and then process them on the 'sync' event, ie. + // each time a sync has completed. This way, we can avoid emitting incoming + // call events if we get both the invite and answer/hangup in the same sync. + // This happens quite often, eg. replaying sync from storage, catchup sync + // after loading and after we've been offline for a bit. let callEventBuffer = []; - let isClientSyncing = false; - const onSync = function(state) { + function onSync(state) { if (state === "SYNCING") { - isClientSyncing = true; - client.removeListener("sync", onSync); - const ignoreCallIds = {}; // Set // inspect the buffer and mark all calls which have been answered // or hung up before passing them to the call event handler. @@ -4658,8 +4658,8 @@ function setupCallEventHandler(client) { } // now loop through the buffer chronologically and inject them callEventBuffer.forEach(function(e) { - if (ignoreCallIds[e.getContent().call_id]) { - // This call has previously been ansered or hung up: ignore it + if (e.getType() === "m.call.invite" && ignoreCallIds[e.getContent().call_id]) { + // This call has previously been answered or hung up: ignore it return; } callEventHandler(e); @@ -4669,8 +4669,6 @@ function setupCallEventHandler(client) { }; client.on("sync", onSync); - client.on("event", onEvent); - function onEvent(event) { if (event.getType().indexOf("m.call.") !== 0) { // not a call event @@ -4680,12 +4678,11 @@ function setupCallEventHandler(client) { } return; } - if (!isClientSyncing) { - callEventBuffer.push(event); - return; - } - callEventHandler(event); + // queue up for processing once all events from this sync have been + // processed (see above). + callEventBuffer.push(event); } + client.on("event", onEvent); function callEventHandler(event) { const content = event.getContent(); From 5262d716e4d63da680d549de4dc233021a2a1021 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 21 Nov 2019 19:10:27 +0000 Subject: [PATCH 2/2] Lint --- src/client.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/client.js b/src/client.js index 410b0e78b..2a7654bfc 100644 --- a/src/client.js +++ b/src/client.js @@ -4658,7 +4658,10 @@ function setupCallEventHandler(client) { } // now loop through the buffer chronologically and inject them callEventBuffer.forEach(function(e) { - if (e.getType() === "m.call.invite" && ignoreCallIds[e.getContent().call_id]) { + if ( + e.getType() === "m.call.invite" && + ignoreCallIds[e.getContent().call_id] + ) { // This call has previously been answered or hung up: ignore it return; } @@ -4666,7 +4669,7 @@ function setupCallEventHandler(client) { }); callEventBuffer = []; } - }; + } client.on("sync", onSync); function onEvent(event) {