perf: merge client status in linear time (#2703)
perf: merge client status in linear time (#2700) Co-authored-by: potatosips <potatosips@users.noreply.github.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import fs from 'node:fs/promises';
|
||||
import { createDebug } from 'obug';
|
||||
|
||||
import Database from '#server/utils/Database';
|
||||
import { mergeClientStatuses } from '#server/utils/clientStatus';
|
||||
import { OLD_ENV, WG_ENV } from '#server/utils/config';
|
||||
import { firewall } from '#server/utils/firewall';
|
||||
import { encodeQRCode } from '#server/utils/qr';
|
||||
@@ -103,21 +104,7 @@ class WireGuard {
|
||||
|
||||
// Loop WireGuard status
|
||||
const dump = await wg.dump(wgInterface.name);
|
||||
dump.forEach(
|
||||
({ publicKey, latestHandshakeAt, endpoint, transferRx, transferTx }) => {
|
||||
const client = clients.find((client) => client.publicKey === publicKey);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
client.latestHandshakeAt = latestHandshakeAt;
|
||||
client.endpoint = endpoint;
|
||||
client.transferRx = transferRx;
|
||||
client.transferTx = transferTx;
|
||||
}
|
||||
);
|
||||
|
||||
return clients;
|
||||
return mergeClientStatuses(clients, dump);
|
||||
}
|
||||
|
||||
async dumpByPublicKey(publicKey: string) {
|
||||
@@ -146,21 +133,7 @@ class WireGuard {
|
||||
|
||||
// Loop WireGuard status
|
||||
const dump = await wg.dump(wgInterface.name);
|
||||
dump.forEach(
|
||||
({ publicKey, latestHandshakeAt, endpoint, transferRx, transferTx }) => {
|
||||
const client = clients.find((client) => client.publicKey === publicKey);
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
client.latestHandshakeAt = latestHandshakeAt;
|
||||
client.endpoint = endpoint;
|
||||
client.transferRx = transferRx;
|
||||
client.transferTx = transferTx;
|
||||
}
|
||||
);
|
||||
|
||||
return clients;
|
||||
return mergeClientStatuses(clients, dump);
|
||||
}
|
||||
|
||||
async getClientConfiguration({ clientId }: { clientId: ID }) {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
type StatusFields = {
|
||||
publicKey: string;
|
||||
latestHandshakeAt: Date | null;
|
||||
endpoint: string | null;
|
||||
transferRx: number | null;
|
||||
transferTx: number | null;
|
||||
};
|
||||
|
||||
export function mergeClientStatuses<T extends StatusFields>(
|
||||
clients: T[],
|
||||
statuses: readonly StatusFields[]
|
||||
): T[] {
|
||||
const clientsByPublicKey = new Map(
|
||||
clients.map((client) => [client.publicKey, client])
|
||||
);
|
||||
|
||||
for (const status of statuses) {
|
||||
const client = clientsByPublicKey.get(status.publicKey);
|
||||
if (!client) {
|
||||
continue;
|
||||
}
|
||||
|
||||
client.latestHandshakeAt = status.latestHandshakeAt;
|
||||
client.endpoint = status.endpoint;
|
||||
client.transferRx = status.transferRx;
|
||||
client.transferTx = status.transferTx;
|
||||
}
|
||||
|
||||
return clients;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { mergeClientStatuses } from '#server/utils/clientStatus';
|
||||
|
||||
describe('mergeClientStatuses', () => {
|
||||
test('merges matching status records by public key', () => {
|
||||
const clients = [
|
||||
{
|
||||
id: 1,
|
||||
publicKey: 'first',
|
||||
latestHandshakeAt: null,
|
||||
endpoint: null,
|
||||
transferRx: null,
|
||||
transferTx: null,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
publicKey: 'second',
|
||||
latestHandshakeAt: null,
|
||||
endpoint: null,
|
||||
transferRx: null,
|
||||
transferTx: null,
|
||||
},
|
||||
];
|
||||
const handshake = new Date('2026-07-20T00:00:00Z');
|
||||
|
||||
const result = mergeClientStatuses(clients, [
|
||||
{
|
||||
publicKey: 'second',
|
||||
latestHandshakeAt: handshake,
|
||||
endpoint: '192.0.2.1:51820',
|
||||
transferRx: 100,
|
||||
transferTx: 200,
|
||||
},
|
||||
{
|
||||
publicKey: 'unknown',
|
||||
latestHandshakeAt: null,
|
||||
endpoint: null,
|
||||
transferRx: 0,
|
||||
transferTx: 0,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(result).toBe(clients);
|
||||
expect(result[0]?.endpoint).toBeNull();
|
||||
expect(result[1]).toMatchObject({
|
||||
latestHandshakeAt: handshake,
|
||||
endpoint: '192.0.2.1:51820',
|
||||
transferRx: 100,
|
||||
transferTx: 200,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user