refactor(session): 升级存储系统架构
- 添加读写锁机制防止并发写入冲突 - 实现数据迁移框架支持版本化升级 - 分层存储结构:项目/会话/消息独立存储 - 使用 Git root commit hash 作为稳定项目 ID - 增量消息同步避免重复写入 - 每条消息独立文件,按序号命名 (0001.json, 0002.json)
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* 进程内读写锁模块
|
||||
* 参考 OpenCode 的实现,支持 using 语法
|
||||
*/
|
||||
|
||||
export namespace Lock {
|
||||
const locks = new Map<
|
||||
string,
|
||||
{
|
||||
readers: number;
|
||||
writer: boolean;
|
||||
waitingReaders: (() => void)[];
|
||||
waitingWriters: (() => void)[];
|
||||
}
|
||||
>();
|
||||
|
||||
function get(key: string) {
|
||||
if (!locks.has(key)) {
|
||||
locks.set(key, {
|
||||
readers: 0,
|
||||
writer: false,
|
||||
waitingReaders: [],
|
||||
waitingWriters: [],
|
||||
});
|
||||
}
|
||||
return locks.get(key)!;
|
||||
}
|
||||
|
||||
function process(key: string) {
|
||||
const lock = locks.get(key);
|
||||
if (!lock || lock.writer || lock.readers > 0) return;
|
||||
|
||||
// 优先处理写锁,防止写饥饿
|
||||
if (lock.waitingWriters.length > 0) {
|
||||
const nextWriter = lock.waitingWriters.shift()!;
|
||||
nextWriter();
|
||||
return;
|
||||
}
|
||||
|
||||
// 唤醒所有等待的读锁
|
||||
while (lock.waitingReaders.length > 0) {
|
||||
const nextReader = lock.waitingReaders.shift()!;
|
||||
nextReader();
|
||||
}
|
||||
|
||||
// 清理空闲锁
|
||||
if (
|
||||
lock.readers === 0 &&
|
||||
!lock.writer &&
|
||||
lock.waitingReaders.length === 0 &&
|
||||
lock.waitingWriters.length === 0
|
||||
) {
|
||||
locks.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取读锁
|
||||
* 多个读锁可以同时持有,但会被写锁阻塞
|
||||
*/
|
||||
export async function read(key: string): Promise<Disposable> {
|
||||
const lock = get(key);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
if (!lock.writer && lock.waitingWriters.length === 0) {
|
||||
lock.readers++;
|
||||
resolve({
|
||||
[Symbol.dispose]: () => {
|
||||
lock.readers--;
|
||||
process(key);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
lock.waitingReaders.push(() => {
|
||||
lock.readers++;
|
||||
resolve({
|
||||
[Symbol.dispose]: () => {
|
||||
lock.readers--;
|
||||
process(key);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取写锁
|
||||
* 写锁是排他的,必须等待所有读锁和写锁释放
|
||||
*/
|
||||
export async function write(key: string): Promise<Disposable> {
|
||||
const lock = get(key);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
if (!lock.writer && lock.readers === 0) {
|
||||
lock.writer = true;
|
||||
resolve({
|
||||
[Symbol.dispose]: () => {
|
||||
lock.writer = false;
|
||||
process(key);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
lock.waitingWriters.push(() => {
|
||||
lock.writer = true;
|
||||
resolve({
|
||||
[Symbol.dispose]: () => {
|
||||
lock.writer = false;
|
||||
process(key);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 带读锁执行操作
|
||||
*/
|
||||
export async function withRead<T>(key: string, fn: () => Promise<T>): Promise<T> {
|
||||
using _ = await read(key);
|
||||
return fn();
|
||||
}
|
||||
|
||||
/**
|
||||
* 带写锁执行操作
|
||||
*/
|
||||
export async function withWrite<T>(key: string, fn: () => Promise<T>): Promise<T> {
|
||||
using _ = await write(key);
|
||||
return fn();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user