mirror of
https://github.com/the-draupnir-project/Draupnir.git
synced 2026-03-30 11:00:13 +00:00
We have a lot of verbose headers, and i think now is the best opportunity we have to become reuse compliant given that we just did two other similar maintenance changes (prettier, typescirpt5 & eslint9 & typescript-eslint). * synapse_antispam resuse headers. * delete old unused tslint.json. * Add REUSE to pre-commit config. * reuse info for config directory.
128 lines
3.9 KiB
TypeScript
128 lines
3.9 KiB
TypeScript
// Copyright 2023 - 2024 Gnuxie <Gnuxie@protonmail.com>
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import { MatrixClient } from "matrix-bot-sdk";
|
|
|
|
/**
|
|
* This is a test for the response times for various endpoints querying the
|
|
* members in a room so that they can be banned.
|
|
*
|
|
* Below are some results from MatrixHQ using a home connection with only 26Mbps down.
|
|
* Which is probably a major limiting factor of these results given the size just encoding the usernames
|
|
* in MatrixHQ alone.
|
|
*
|
|
* /joined_members: total time elapsed 29.655seconds, mean time 5931ms, median time 4744ms
|
|
* /state: total time elapsed 141.353seconds, mean time 28270.6ms, median time 23354ms
|
|
* /members: total time elapsed 164.845seconds, mean time 32969ms, median time 28258ms
|
|
*
|
|
* To run the script use `yarn ts-node -P tsconfig.json test/scripts/memberQueryTest.ts`.
|
|
*/
|
|
//
|
|
const accessToken = "redacted";
|
|
const client = new MatrixClient(
|
|
"https://matrix-client.matrix.org",
|
|
accessToken
|
|
);
|
|
const roomId = "!OGEhHVWSdvArJzumhm:matrix.org";
|
|
|
|
enum MemberFetchMethod {
|
|
JoinedMembers = "/joined_members",
|
|
Members = "/members",
|
|
State = "/state",
|
|
}
|
|
|
|
const shuffledMethods = [
|
|
MemberFetchMethod.JoinedMembers,
|
|
MemberFetchMethod.Members,
|
|
MemberFetchMethod.State,
|
|
].reduce((acc: MemberFetchMethod[], method: MemberFetchMethod) => {
|
|
return [...acc, ...[...Array(5)].map((_) => method)];
|
|
}, []);
|
|
|
|
// shuffle https://stackoverflow.com/a/12646864
|
|
for (let i = shuffledMethods.length - 1; i > 0; i--) {
|
|
const j = Math.floor(Math.random() * (i + 1));
|
|
const [methodJ, methodI] = [shuffledMethods[j], shuffledMethods[i]];
|
|
if (methodJ && methodI) {
|
|
[shuffledMethods[i], shuffledMethods[j]] = [methodJ, methodI];
|
|
}
|
|
}
|
|
|
|
async function fetchStateWithMethod(method: MemberFetchMethod) {
|
|
switch (method) {
|
|
case MemberFetchMethod.JoinedMembers:
|
|
return await client.getJoinedRoomMembers(roomId);
|
|
case MemberFetchMethod.Members:
|
|
return await client.getRoomMembers(roomId, undefined, undefined, [
|
|
"leave",
|
|
"ban",
|
|
]);
|
|
case MemberFetchMethod.State:
|
|
return await client.getRoomState(roomId);
|
|
default:
|
|
throw new TypeError();
|
|
}
|
|
}
|
|
|
|
const times = new Map<MemberFetchMethod, number[]>([
|
|
[MemberFetchMethod.JoinedMembers, []],
|
|
[MemberFetchMethod.Members, []],
|
|
[MemberFetchMethod.State, []],
|
|
]);
|
|
|
|
function addTime(method: MemberFetchMethod, time: number) {
|
|
const entry = times.get(method);
|
|
if (entry === undefined) {
|
|
throw new TypeError();
|
|
}
|
|
entry.push(time);
|
|
}
|
|
|
|
function getTimes(method: MemberFetchMethod) {
|
|
return times.get(method);
|
|
}
|
|
|
|
function evenMedian(s: number[], mid: number): number | undefined {
|
|
const leftMid = s[mid - 1];
|
|
const rightMid = s[mid];
|
|
if (leftMid === undefined || rightMid === undefined) {
|
|
throw new TypeError(`Code is wrong bozo`);
|
|
}
|
|
return (leftMid + rightMid) / 2;
|
|
}
|
|
|
|
// https://stackoverflow.com/a/70806192
|
|
function calculateMedian(arr: number[]): number | undefined {
|
|
if (!arr.length) return undefined;
|
|
const s = [...arr].sort((a, b) => a - b);
|
|
const mid = Math.floor(s.length / 2);
|
|
return s.length % 2 === 0 ? evenMedian(s, mid) : s[mid];
|
|
}
|
|
|
|
void (async () => {
|
|
for (const method of shuffledMethods) {
|
|
const start = Date.now();
|
|
await fetchStateWithMethod(method);
|
|
const elapsedMs = Date.now() - start;
|
|
addTime(method, elapsedMs);
|
|
}
|
|
|
|
for (const method of [
|
|
MemberFetchMethod.JoinedMembers,
|
|
MemberFetchMethod.Members,
|
|
MemberFetchMethod.State,
|
|
]) {
|
|
const nextTimes = getTimes(method);
|
|
if (nextTimes === undefined) {
|
|
throw new TypeError(`Times shouldn't be undefined matey`);
|
|
}
|
|
const sum = nextTimes.reduce((a, b) => a + b, 0);
|
|
const mean = sum / nextTimes.length || 0;
|
|
const median = calculateMedian(nextTimes);
|
|
console.log(
|
|
`${method}: total time elapsed ${sum / 1000}seconds, mean time ${mean}ms, median time ${median}ms`
|
|
);
|
|
}
|
|
})();
|