From 4b820dc90af8d71c81066690f1601db50c2619be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 18 Nov 2021 10:00:02 +0100 Subject: [PATCH] Do not emit "change" events if attribute did not change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "change:XXX" events should be emitted only if XXX actually changed. In most cases the duplicated events were not a problem, but when background blur was enabled in a call with more than 5 participants it could cause the browser to crash. SentVideoQualityThrottler starts listening to events when video becomes available, so if "change:videoAvailable(true)" was emitted again the event handlers were duplicated. One of the handlers was set for the "speaking" event, which causes the video quality to be adjusted if needed. When background blur is enabled adjusting the video quality restarts the effect, which causes the video stream to be recreated, which in turn caused "change:videoAvailable(true)" to be emitted. Due to all this, whenever the user spoke in a large call after another user had spoken the event handlers for the "speaking" event were duplicated, and each handler execution reset the background blur. Eventually there were so many event handlers for the "speaking" event that stopping and starting again the background blur so many times at once temporary ate all the available memory, even if the objects would have been garbage collected and the memory freed in a normal way later. Signed-off-by: Daniel Calviño Sánchez --- src/utils/webrtc/models/CallParticipantModel.js | 4 ++++ src/utils/webrtc/models/LocalCallParticipantModel.js | 4 ++++ src/utils/webrtc/models/LocalMediaModel.js | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/utils/webrtc/models/CallParticipantModel.js b/src/utils/webrtc/models/CallParticipantModel.js index 5c260f12cde..153abccf937 100644 --- a/src/utils/webrtc/models/CallParticipantModel.js +++ b/src/utils/webrtc/models/CallParticipantModel.js @@ -118,6 +118,10 @@ CallParticipantModel.prototype = { }, set(key, value) { + if (this.attributes[key] === value) { + return + } + this.attributes[key] = value this._trigger('change:' + key, [value]) diff --git a/src/utils/webrtc/models/LocalCallParticipantModel.js b/src/utils/webrtc/models/LocalCallParticipantModel.js index 112a51624ed..27219e53807 100644 --- a/src/utils/webrtc/models/LocalCallParticipantModel.js +++ b/src/utils/webrtc/models/LocalCallParticipantModel.js @@ -51,6 +51,10 @@ LocalCallParticipantModel.prototype = { }, set(key, value) { + if (this.attributes[key] === value) { + return + } + this.attributes[key] = value this._trigger('change:' + key, [value]) diff --git a/src/utils/webrtc/models/LocalMediaModel.js b/src/utils/webrtc/models/LocalMediaModel.js index ed62bfdf1a7..3f87eb8c262 100644 --- a/src/utils/webrtc/models/LocalMediaModel.js +++ b/src/utils/webrtc/models/LocalMediaModel.js @@ -77,6 +77,10 @@ LocalMediaModel.prototype = { }, set(key, value) { + if (this.attributes[key] === value) { + return + } + this.attributes[key] = value this._trigger('change:' + key, [value])