memorium/lib/cache/performance.ts

82 lines
1.9 KiB
TypeScript
Raw Normal View History

2023-08-13 00:34:03 +02:00
import * as cache from "@lib/cache/cache.ts";
2023-08-13 02:26:22 +02:00
import { getTimeCacheKey } from "@lib/string.ts";
2023-08-13 00:34:03 +02:00
export type PerformancePoint = {
path: string;
search: string;
time: number;
date: Date;
};
export type PerformanceRes = {
max: number;
res: {
url: string;
data: readonly [number, number, number, number];
}[];
};
export const savePerformance = (url: string, milliseconds: number) => {
2023-08-13 02:26:22 +02:00
const cacheKey = getTimeCacheKey();
2023-08-13 00:34:03 +02:00
const u = new URL(url);
if (u.pathname.includes("_frsh/")) return;
u.searchParams.delete("__frsh_c");
cache.set(
2023-08-13 02:26:22 +02:00
`performance:${cacheKey}`,
2023-08-13 00:34:03 +02:00
JSON.stringify({
path: decodeURIComponent(u.pathname),
search: u.search,
time: Math.floor(milliseconds * 1000),
}),
);
};
export async function getPerformances(): Promise<PerformanceRes> {
const d = new Date();
const year = d.getFullYear();
const month = d.getMonth().toString().padStart(2, "0");
const day = d.getDay().toString().padStart(2, "0");
const keys = await cache.keys(
`performance:${year}:${month}:${day}:*`,
);
const performances = await Promise.all(
keys.map(async (key) =>
JSON.parse(await cache.get<string>(key)) as PerformancePoint
),
);
let maximum = 0;
const res = new Map<string, number[]>();
for (const p of performances) {
const id = p.path;
const timings = res.get(id) || [];
if (p.time > maximum) maximum = p.time;
timings.push(p.time);
res.set(id, timings);
}
return {
max: maximum,
res: [...res.entries()].map(([url, timings]) => {
let total = 0;
let min = Infinity;
let max = -Infinity;
for (const t of timings) {
total += t;
if (t < min) min = t;
if (t > max) max = t;
}
return {
url,
data: [timings.length, min, total / timings.length, max] as const,
};
}).sort((a, b) => a.data[2] < b.data[2] ? 1 : -1),
};
}