@syngrisi/syngrisi
Version:
Syngrisi - Visual Testing Tool
85 lines (73 loc) • 2.66 kB
text/typescript
import log from '@logger';
import { appSettings } from '@settings';
import { env } from '@/server/envConfig';
import { errMsg } from '@/server/utils';
type AutoCleanupValue = {
days?: number;
lastRunAt?: string | null;
};
interface SchedulerOptions {
settingName: string;
defaultDays: number;
scope: string;
runTask: (days: number) => Promise<void>;
}
export class AutoCleanupScheduler {
private timer: NodeJS.Timeout | null = null;
private running = false;
constructor(private options: SchedulerOptions) { }
start(): void {
if (this.timer) {
return;
}
const intervalMs = env.SYNGRISI_AUTO_REMOVE_CHECKS_POLL_INTERVAL_MS;
this.timer = setInterval(() => {
void this.tick();
}, intervalMs);
void this.tick();
log.info(`scheduler started (poll every ${intervalMs}ms)`, { scope: this.options.scope });
}
stop(): void {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
log.info(`scheduler stopped`, { scope: this.options.scope });
}
}
private async tick(): Promise<void> {
if (this.running) {
return;
}
this.running = true;
try {
const AppSettings = appSettings;
const setting = await AppSettings.get(this.options.settingName);
if (!setting || !setting.enabled) {
return;
}
const value: AutoCleanupValue = setting.value ?? {};
const days = typeof value.days === 'number' && value.days >= 0
? value.days
: this.options.defaultDays;
const lastRunAt = value.lastRunAt ? new Date(value.lastRunAt) : null;
const now = Date.now();
const minInterval = env.SYNGRISI_AUTO_REMOVE_CHECKS_MIN_INTERVAL_MS;
const shouldRun = !lastRunAt || (now - lastRunAt.getTime()) >= minInterval;
if (!shouldRun) {
return;
}
log.info(`triggering cleanup for items older than ${days} days`, { scope: this.options.scope });
await this.options.runTask(days);
await AppSettings.set(this.options.settingName, {
...value,
days,
lastRunAt: new Date(now).toISOString(),
});
log.info(`cleanup completed`, { scope: this.options.scope });
} catch (error) {
log.error(`scheduler error: ${errMsg(error)}`, { scope: this.options.scope });
} finally {
this.running = false;
}
}
}