Spaces:
Sleeping
Sleeping
File size: 2,027 Bytes
ed57015 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | import { getDb } from '../db/index.js';
const DAY_MS = 24 * 60 * 60 * 1000;
const DEFAULT_RETENTION_DAYS = 90;
const DEFAULT_MAX_ROWS = 100_000;
const PRUNE_INTERVAL_MS = 60_000;
type RetentionDb = ReturnType<typeof getDb>;
export interface RequestAnalyticsRetentionConfig {
retentionDays: number;
maxRows: number;
}
let nextPruneAtMs = 0;
function readNonNegativeInt(name: string, defaultValue: number): number {
const raw = process.env[name];
if (raw === undefined || raw.trim() === '') return defaultValue;
const parsed = Number(raw);
if (!Number.isInteger(parsed) || parsed < 0) return defaultValue;
return parsed;
}
function toSqliteTimestamp(date: Date): string {
return date.toISOString().slice(0, 19).replace('T', ' ');
}
export function getRequestAnalyticsRetentionConfig(): RequestAnalyticsRetentionConfig {
return {
retentionDays: readNonNegativeInt('REQUEST_ANALYTICS_RETENTION_DAYS', DEFAULT_RETENTION_DAYS),
maxRows: readNonNegativeInt('REQUEST_ANALYTICS_MAX_ROWS', DEFAULT_MAX_ROWS),
};
}
export function pruneRequestAnalytics(options: {
db?: RetentionDb;
force?: boolean;
now?: Date;
} = {}): { deleted: number; skipped: boolean } {
const now = options.now ?? new Date();
const nowMs = now.getTime();
if (!options.force && nowMs < nextPruneAtMs) {
return { deleted: 0, skipped: true };
}
nextPruneAtMs = nowMs + PRUNE_INTERVAL_MS;
const db = options.db ?? getDb();
const { retentionDays, maxRows } = getRequestAnalyticsRetentionConfig();
let deleted = 0;
if (retentionDays > 0) {
const cutoff = toSqliteTimestamp(new Date(nowMs - retentionDays * DAY_MS));
deleted += db.prepare('DELETE FROM requests WHERE created_at < ?').run(cutoff).changes;
}
if (maxRows > 0) {
deleted += db.prepare(`
DELETE FROM requests
WHERE id IN (
SELECT id
FROM requests
ORDER BY created_at DESC, id DESC
LIMIT -1 OFFSET ?
)
`).run(maxRows).changes;
}
return { deleted, skipped: false };
}
|