fix(session): 修复 getOrCreateProject 死锁问题

读写锁嵌套导致死锁:在持有读锁的情况下尝试获取写锁。
改为先释放读锁再获取写锁,并使用双重检查模式防止竞态条件。
This commit is contained in:
2025-12-14 20:44:55 +08:00
parent 70a9a154a4
commit c9d0cbce5b
+17 -4
View File
@@ -83,13 +83,28 @@ export class SessionStorage {
const projectId = await getProjectId(workdir);
const projectFile = path.join(this.projectDir, `${projectId}.json`);
// 先尝试读取(只需读锁)
{
using _ = await Lock.read(projectFile);
try {
const content = await fs.readFile(projectFile, 'utf-8');
return JSON.parse(content) as ProjectMetadata;
} catch {
// 项目不存在,创建新项目
// 项目不存在,需要创建
}
}
// 读锁已释放,获取写锁来创建项目
using _ = await Lock.write(projectFile);
// 双重检查:可能其他进程已经创建了
try {
const content = await fs.readFile(projectFile, 'utf-8');
return JSON.parse(content) as ProjectMetadata;
} catch {
// 确实不存在,创建新项目
}
const isGitRepo = await isGitRepository(workdir);
const project: ProjectMetadata = {
id: projectId,
@@ -98,7 +113,6 @@ export class SessionStorage {
isGitRepo,
};
using __ = await Lock.write(projectFile);
await fs.writeFile(projectFile, JSON.stringify(project, null, 2), 'utf-8');
// 确保项目的会话目录存在
@@ -106,7 +120,6 @@ export class SessionStorage {
return project;
}
}
// ========== 会话元数据管理 ==========