From 81cda7c7495b06de3c6d4d37bcffcdbfafd87209 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 23 Feb 2022 19:16:12 +0000 Subject: [PATCH] Fix freeze on room switch (#7884) * Fix freeze on room switch updateServerCandidates was called on every room member event and not throttled. Fixes https://github.com/vector-im/element-web/issues/21127 * Move import * Disable throttling in tests * Types Co-authored-by: Travis Ralston Co-authored-by: Travis Ralston --- src/utils/permalinks/Permalinks.ts | 16 +++++++++++++--- test/utils/permalinks/Permalinks-test.js | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/utils/permalinks/Permalinks.ts b/src/utils/permalinks/Permalinks.ts index b1a01b28c3..6e8d3fd915 100644 --- a/src/utils/permalinks/Permalinks.ts +++ b/src/utils/permalinks/Permalinks.ts @@ -15,6 +15,7 @@ limitations under the License. */ import isIp from "is-ip"; +import { throttle } from "lodash"; import * as utils from "matrix-js-sdk/src/utils"; import { Room } from "matrix-js-sdk/src/models/room"; import { EventType } from "matrix-js-sdk/src/@types/event"; @@ -91,7 +92,10 @@ export class RoomPermalinkCreator { // We support being given a roomId as a fallback in the event the `room` object // doesn't exist or is not healthy for us to rely on. For example, loading a // permalink to a room which the MatrixClient doesn't know about. - constructor(room: Room, roomId: string = null) { + // Some of the tests done by this class are relatively expensive, so normally + // throttled to not happen on every update. Pass false as the shouldThrottle + // param to disable this behaviour, eg. for tests. + constructor(room: Room, roomId: string | null = null, shouldThrottle = true) { this.room = room; this.roomId = room ? room.roomId : roomId; this.highestPlUserId = null; @@ -104,6 +108,12 @@ export class RoomPermalinkCreator { if (!this.roomId) { throw new Error("Failed to resolve a roomId for the permalink creator to use"); } + + if (shouldThrottle) { + this.updateServerCandidates = throttle( + this.updateServerCandidates, 200, { leading: true, trailing: true }, + ); + } } load() { @@ -260,7 +270,7 @@ export class RoomPermalinkCreator { this.populationMap = populationMap; } - private updateServerCandidates() { + private updateServerCandidates = () => { let candidates = []; if (this.highestPlUserId) { candidates.push(getServerName(this.highestPlUserId)); @@ -279,7 +289,7 @@ export class RoomPermalinkCreator { candidates = candidates.concat(remainingServers); this._serverCandidates = candidates; - } + }; } export function makeGenericPermalink(entityId: string): string { diff --git a/test/utils/permalinks/Permalinks-test.js b/test/utils/permalinks/Permalinks-test.js index a338706a81..9d311d5f42 100644 --- a/test/utils/permalinks/Permalinks-test.js +++ b/test/utils/permalinks/Permalinks-test.js @@ -122,7 +122,7 @@ describe('Permalinks', function() { }, member95, ]); - const creator = new RoomPermalinkCreator(room); + const creator = new RoomPermalinkCreator(room, null, false); creator.load(); expect(creator._serverCandidates[0]).toBe("pl_95"); member95.membership = "left";