Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit b114c5e

Browse files
authored
Improve performance of switching to rooms with lots of servers and ACLs (#8347)
* Improve performance of switching to rooms with lots of servers and ACLs By not processing the *entire* list of servers and ACLs when determining how to create permalinks, this shaves ~100 ms off of switches into high-traffic rooms. * Fix lint * Ensure that permalink server candidates can't be duplicates
1 parent 7c41b86 commit b114c5e

File tree

1 file changed

+19
-19
lines changed

1 file changed

+19
-19
lines changed

src/utils/permalinks/Permalinks.ts

+19-19
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,6 @@ export class RoomPermalinkCreator {
166166
// updates, but they were on member events which can be very numerous, so the incremental
167167
// updates ended up being much slower than a full update. We now have the batch state update
168168
// event, so we just update in full, but on each batch of updates.
169-
// A full update takes about 120ms for me on Matrix HQ, which still feels like way too long
170-
// to be spending worrying about how we might generate a permalink, but it's better than
171-
// multiple seconds.
172169
this.updateAllowedServers();
173170
this.updateHighestPlUser();
174171
this.updatePopulationMap();
@@ -241,24 +238,27 @@ export class RoomPermalinkCreator {
241238
}
242239

243240
private updateServerCandidates = () => {
244-
let candidates = [];
241+
const candidates = new Set<string>();
245242
if (this.highestPlUserId) {
246-
candidates.push(getServerName(this.highestPlUserId));
243+
candidates.add(getServerName(this.highestPlUserId));
247244
}
248245

249246
const serversByPopulation = Object.keys(this.populationMap)
250-
.sort((a, b) => this.populationMap[b] - this.populationMap[a])
251-
.filter(a => {
252-
return !candidates.includes(a) &&
253-
!isHostnameIpAddress(a) &&
254-
!isHostInRegex(a, this.bannedHostsRegexps) &&
255-
isHostInRegex(a, this.allowedHostsRegexps);
256-
});
257-
258-
const remainingServers = serversByPopulation.slice(0, MAX_SERVER_CANDIDATES - candidates.length);
259-
candidates = candidates.concat(remainingServers);
260-
261-
this._serverCandidates = candidates;
247+
.sort((a, b) => this.populationMap[b] - this.populationMap[a]);
248+
249+
for (let i = 0; i < serversByPopulation.length && candidates.size < MAX_SERVER_CANDIDATES; i++) {
250+
const server = serversByPopulation[i];
251+
if (
252+
!candidates.has(server) &&
253+
!isHostnameIpAddress(server) &&
254+
!isHostInRegex(server, this.bannedHostsRegexps) &&
255+
isHostInRegex(server, this.allowedHostsRegexps)
256+
) {
257+
candidates.add(server);
258+
}
259+
}
260+
261+
this._serverCandidates = [...candidates];
262262
};
263263
}
264264

@@ -447,12 +447,12 @@ function getHostnameFromMatrixDomain(domain: string): string {
447447
return new URL(`https://${domain}`).hostname;
448448
}
449449

450-
function isHostInRegex(hostname: string, regexps: RegExp[]) {
450+
function isHostInRegex(hostname: string, regexps: RegExp[]): boolean {
451451
hostname = getHostnameFromMatrixDomain(hostname);
452452
if (!hostname) return true; // assumed
453453
if (regexps.length > 0 && !regexps[0].test) throw new Error(regexps[0].toString());
454454

455-
return regexps.filter(h => h.test(hostname)).length > 0;
455+
return regexps.some(h => h.test(hostname));
456456
}
457457

458458
function isHostnameIpAddress(hostname: string): boolean {

0 commit comments

Comments
 (0)