fix(snapshot): onModuleInit 增加扫描临时目录清理孤儿文件
SQLite 可能因重建丢失任务记录,导致 onModuleInit 仅靠查数据库 无法清理遗留的临时目录。新增逻辑:启动时扫描临时目录所有子目录, 若数据库中不存在对应任务则直接删除。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
669a8a7248
commit
7b7bfcac93
|
|
@ -36,12 +36,23 @@ export class SnapshotOrchestratorService implements OnModuleInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
async onModuleInit(): Promise<void> {
|
async onModuleInit(): Promise<void> {
|
||||||
|
// 1. 标记数据库中遗留的 RUNNING 任务为 FAILED
|
||||||
const stale = await this.repo.findByStatus(SnapshotStatus.RUNNING);
|
const stale = await this.repo.findByStatus(SnapshotStatus.RUNNING);
|
||||||
for (const task of stale) {
|
for (const task of stale) {
|
||||||
await this.repo.updateTaskStatus(task.id, SnapshotStatus.FAILED, '服务重启,任务中断');
|
await this.repo.updateTaskStatus(task.id, SnapshotStatus.FAILED, '服务重启,任务中断');
|
||||||
this.localStorage.deleteTask(task.id);
|
this.localStorage.deleteTask(task.id);
|
||||||
this.logger.warn(`遗留任务已标记失败: ${task.id}`);
|
this.logger.warn(`遗留任务已标记失败: ${task.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. 扫描临时目录,清理数据库中不存在的孤儿目录
|
||||||
|
const dirIds = this.localStorage.listTaskDirs();
|
||||||
|
for (const dirId of dirIds) {
|
||||||
|
const task = await this.repo.findById(dirId);
|
||||||
|
if (!task) {
|
||||||
|
this.localStorage.deleteTask(dirId);
|
||||||
|
this.logger.warn(`清理孤儿临时目录: ${dirId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getAvailableTargets(): BackupTarget[] {
|
getAvailableTargets(): BackupTarget[] {
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,14 @@ export class LocalStorageAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 列出临时目录中所有任务子目录的 ID */
|
||||||
|
listTaskDirs(): string[] {
|
||||||
|
if (!fs.existsSync(this.tempDir)) return [];
|
||||||
|
return fs.readdirSync(this.tempDir, { withFileTypes: true })
|
||||||
|
.filter((e) => e.isDirectory())
|
||||||
|
.map((e) => e.name);
|
||||||
|
}
|
||||||
|
|
||||||
cleanupExpired(retentionHours: number): string[] {
|
cleanupExpired(retentionHours: number): string[] {
|
||||||
const threshold = Date.now() - retentionHours * 60 * 60 * 1000;
|
const threshold = Date.now() - retentionHours * 60 * 60 * 1000;
|
||||||
const deletedIds: string[] = [];
|
const deletedIds: string[] = [];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue