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 <travisr@matrix.org>

Co-authored-by: Travis Ralston <travisr@matrix.org>
This commit is contained in:
David Baker 2022-02-23 19:16:12 +00:00 committed by GitHub
parent 5c5dc69547
commit 81cda7c749
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 4 deletions

View file

@ -15,6 +15,7 @@ limitations under the License.
*/ */
import isIp from "is-ip"; import isIp from "is-ip";
import { throttle } from "lodash";
import * as utils from "matrix-js-sdk/src/utils"; import * as utils from "matrix-js-sdk/src/utils";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { EventType } from "matrix-js-sdk/src/@types/event"; 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 // 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 // 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. // 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.room = room;
this.roomId = room ? room.roomId : roomId; this.roomId = room ? room.roomId : roomId;
this.highestPlUserId = null; this.highestPlUserId = null;
@ -104,6 +108,12 @@ export class RoomPermalinkCreator {
if (!this.roomId) { if (!this.roomId) {
throw new Error("Failed to resolve a roomId for the permalink creator to use"); 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() { load() {
@ -260,7 +270,7 @@ export class RoomPermalinkCreator {
this.populationMap = populationMap; this.populationMap = populationMap;
} }
private updateServerCandidates() { private updateServerCandidates = () => {
let candidates = []; let candidates = [];
if (this.highestPlUserId) { if (this.highestPlUserId) {
candidates.push(getServerName(this.highestPlUserId)); candidates.push(getServerName(this.highestPlUserId));
@ -279,7 +289,7 @@ export class RoomPermalinkCreator {
candidates = candidates.concat(remainingServers); candidates = candidates.concat(remainingServers);
this._serverCandidates = candidates; this._serverCandidates = candidates;
} };
} }
export function makeGenericPermalink(entityId: string): string { export function makeGenericPermalink(entityId: string): string {

View file

@ -122,7 +122,7 @@ describe('Permalinks', function() {
}, },
member95, member95,
]); ]);
const creator = new RoomPermalinkCreator(room); const creator = new RoomPermalinkCreator(room, null, false);
creator.load(); creator.load();
expect(creator._serverCandidates[0]).toBe("pl_95"); expect(creator._serverCandidates[0]).toBe("pl_95");
member95.membership = "left"; member95.membership = "left";