feat(storage): add StorageManager and cache subsystem; integrate storage into ConnectionManager and GitopsApp, migrate legacy connections, and add tests
This commit is contained in:
68
ts/cache/classes.cache.cleaner.ts
vendored
Normal file
68
ts/cache/classes.cache.cleaner.ts
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
import { logger } from '../logging.ts';
|
||||
import type { CacheDb } from './classes.cachedb.ts';
|
||||
|
||||
// deno-lint-ignore no-explicit-any
|
||||
type DocumentClass = { getInstances: (filter: any) => Promise<{ delete: () => Promise<void> }[]> };
|
||||
|
||||
const DEFAULT_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
|
||||
|
||||
/**
|
||||
* Periodically cleans up expired cached documents.
|
||||
*/
|
||||
export class CacheCleaner {
|
||||
private intervalId: number | null = null;
|
||||
private intervalMs: number;
|
||||
private documentClasses: DocumentClass[] = [];
|
||||
private cacheDb: CacheDb;
|
||||
|
||||
constructor(cacheDb: CacheDb, intervalMs = DEFAULT_INTERVAL_MS) {
|
||||
this.cacheDb = cacheDb;
|
||||
this.intervalMs = intervalMs;
|
||||
}
|
||||
|
||||
/** Register a document class for cleanup */
|
||||
registerClass(cls: DocumentClass): void {
|
||||
this.documentClasses.push(cls);
|
||||
}
|
||||
|
||||
start(): void {
|
||||
if (this.intervalId !== null) return;
|
||||
this.intervalId = setInterval(() => {
|
||||
this.clean().catch((err) => {
|
||||
logger.error(`CacheCleaner error: ${err}`);
|
||||
});
|
||||
}, this.intervalMs);
|
||||
// Unref so the interval doesn't prevent process exit
|
||||
Deno.unrefTimer(this.intervalId);
|
||||
logger.debug(`CacheCleaner started (interval: ${this.intervalMs}ms)`);
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
if (this.intervalId !== null) {
|
||||
clearInterval(this.intervalId);
|
||||
this.intervalId = null;
|
||||
logger.debug('CacheCleaner stopped');
|
||||
}
|
||||
}
|
||||
|
||||
/** Run a single cleanup pass */
|
||||
async clean(): Promise<number> {
|
||||
const now = Date.now();
|
||||
let totalDeleted = 0;
|
||||
for (const cls of this.documentClasses) {
|
||||
try {
|
||||
const expired = await cls.getInstances({ expiresAt: { $lt: now } });
|
||||
for (const doc of expired) {
|
||||
await doc.delete();
|
||||
totalDeleted++;
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(`CacheCleaner: failed to clean class: ${err}`);
|
||||
}
|
||||
}
|
||||
if (totalDeleted > 0) {
|
||||
logger.debug(`CacheCleaner: deleted ${totalDeleted} expired document(s)`);
|
||||
}
|
||||
return totalDeleted;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user