mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-07-25 12:05:19 +02:00
enhance(dev): tweak get-backend-memory
This commit is contained in:
75
.github/scripts/memory-stability-util.mts
vendored
Normal file
75
.github/scripts/memory-stability-util.mts
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
|
||||
type MemoryStabilityTimer = {
|
||||
now: () => number;
|
||||
wait: (durationMs: number) => Promise<void>;
|
||||
};
|
||||
|
||||
const intervalMs = 2000;
|
||||
const maxWaitMs = 10000;
|
||||
const windowSize = 3;
|
||||
const slopeThresholdKiBPerSecond = 256;
|
||||
const stabilityMetrics = ['Pss', 'Private_Dirty'] as const;
|
||||
|
||||
const defaultTimer: MemoryStabilityTimer = {
|
||||
now: () => performance.now(),
|
||||
wait: durationMs => setTimeout(durationMs),
|
||||
};
|
||||
|
||||
function getMaxAbsoluteSlopes<T extends Record<string, number>>(readings: { elapsedMs: number; memoryUsage: T }[]) {
|
||||
const result = {} as Record<typeof stabilityMetrics[number], number>;
|
||||
|
||||
for (const metric of stabilityMetrics) {
|
||||
let maxAbsoluteSlope = 0;
|
||||
for (let i = 1; i < readings.length; i++) {
|
||||
const previous = readings[i - 1];
|
||||
const current = readings[i];
|
||||
const durationSeconds = (current.elapsedMs - previous.elapsedMs) / 1000;
|
||||
maxAbsoluteSlope = Math.max(maxAbsoluteSlope, Math.abs(current.memoryUsage[metric] - previous.memoryUsage[metric]) / durationSeconds);
|
||||
}
|
||||
result[metric] = maxAbsoluteSlope;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function measureMemoryUntilStable<T extends Record<string, number>>(
|
||||
readMemoryUsage: () => Promise<T>,
|
||||
timer: MemoryStabilityTimer = defaultTimer,
|
||||
) {
|
||||
const startedAt = timer.now();
|
||||
const readings: { elapsedMs: number; memoryUsage: T }[] = [];
|
||||
let maxAbsoluteSlopesKiBPerSecond: Record<typeof stabilityMetrics[number], number> | null = null;
|
||||
|
||||
while (true) {
|
||||
const memoryUsage = await readMemoryUsage();
|
||||
const elapsedMs = timer.now() - startedAt;
|
||||
readings.push({ elapsedMs, memoryUsage });
|
||||
|
||||
let converged = false;
|
||||
if (readings.length >= windowSize) {
|
||||
const latestSlopes = getMaxAbsoluteSlopes(readings.slice(-windowSize));
|
||||
maxAbsoluteSlopesKiBPerSecond = latestSlopes;
|
||||
converged = stabilityMetrics.every(metric => latestSlopes[metric] <= slopeThresholdKiBPerSecond);
|
||||
}
|
||||
|
||||
if (converged || elapsedMs >= maxWaitMs) {
|
||||
return {
|
||||
memoryUsage,
|
||||
stability: {
|
||||
converged,
|
||||
readingCount: readings.length,
|
||||
elapsedMs,
|
||||
maxAbsoluteSlopesKiBPerSecond,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
await timer.wait(Math.min(intervalMs, maxWaitMs - elapsedMs));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user