fix(session): 修复 getOrCreateProject 死锁问题
读写锁嵌套导致死锁:在持有读锁的情况下尝试获取写锁。 改为先释放读锁再获取写锁,并使用双重检查模式防止竞态条件。
This commit is contained in:
@@ -83,13 +83,28 @@ export class SessionStorage {
|
|||||||
const projectId = await getProjectId(workdir);
|
const projectId = await getProjectId(workdir);
|
||||||
const projectFile = path.join(this.projectDir, `${projectId}.json`);
|
const projectFile = path.join(this.projectDir, `${projectId}.json`);
|
||||||
|
|
||||||
|
// 先尝试读取(只需读锁)
|
||||||
|
{
|
||||||
using _ = await Lock.read(projectFile);
|
using _ = await Lock.read(projectFile);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const content = await fs.readFile(projectFile, 'utf-8');
|
const content = await fs.readFile(projectFile, 'utf-8');
|
||||||
return JSON.parse(content) as ProjectMetadata;
|
return JSON.parse(content) as ProjectMetadata;
|
||||||
} catch {
|
} 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 isGitRepo = await isGitRepository(workdir);
|
||||||
const project: ProjectMetadata = {
|
const project: ProjectMetadata = {
|
||||||
id: projectId,
|
id: projectId,
|
||||||
@@ -98,7 +113,6 @@ export class SessionStorage {
|
|||||||
isGitRepo,
|
isGitRepo,
|
||||||
};
|
};
|
||||||
|
|
||||||
using __ = await Lock.write(projectFile);
|
|
||||||
await fs.writeFile(projectFile, JSON.stringify(project, null, 2), 'utf-8');
|
await fs.writeFile(projectFile, JSON.stringify(project, null, 2), 'utf-8');
|
||||||
|
|
||||||
// 确保项目的会话目录存在
|
// 确保项目的会话目录存在
|
||||||
@@ -106,7 +120,6 @@ export class SessionStorage {
|
|||||||
|
|
||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 会话元数据管理 ==========
|
// ========== 会话元数据管理 ==========
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user