fix: serialize diagnostic log appends

这个提交包含在:
Zain 2026-03-19 19:09:56 +08:00
父节点 c187bed711
当前提交 46e14ae2f5
共有 2 个文件被更改,包括 41 次插入 和 6 次删除

查看文件

@ -6,9 +6,12 @@ const MAX_RECENT_LOGS = 300;
type DiagnosticStoreStorage = Pick<StorageManager, 'get' | 'set' | 'remove'>;
export class DiagnosticLogStore {
private appendChain: Promise<void> = Promise.resolve();
constructor(private readonly storageManager: DiagnosticStoreStorage = storage) {}
async append(entry: DiagnosticLogEntry): Promise<void> {
const runAppend = async () => {
const recent = await this.getRecent();
const next = [...recent, entry];
@ -17,6 +20,11 @@ export class DiagnosticLogStore {
}
await this.storageManager.set(DIAGNOSTIC_STORAGE_KEYS.RECENT_LOGS, next);
};
const appendPromise = this.appendChain.then(runAppend, runAppend);
this.appendChain = appendPromise.catch(() => undefined);
return appendPromise;
}
async getRecent(): Promise<DiagnosticLogEntry[]> {

查看文件

@ -54,6 +54,33 @@ describe('DiagnosticLogStore', () => {
expect(logs.at(-1)?.id).toBe('log-304');
});
it('does not lose logs when append is called concurrently', async () => {
let currentLogs: DiagnosticLogEntry[] = [];
const concurrentStorage = {
get: vi.fn(async () => {
const snapshot = [...currentLogs];
await new Promise((resolve) => setTimeout(resolve, 0));
return snapshot;
}),
set: vi.fn(async (_key: string, value: DiagnosticLogEntry[]) => {
currentLogs = value;
}),
remove: vi.fn(async () => {}),
};
const store = new DiagnosticLogStore(concurrentStorage as any);
await Promise.all([
store.append({ id: 'log-a', level: 'INFO', message: 'A' }),
store.append({ id: 'log-b', level: 'INFO', message: 'B' }),
]);
expect(currentLogs).toHaveLength(2);
expect(currentLogs.map((item) => item.id)).toEqual(['log-a', 'log-b']);
});
it('clears the buffer without touching unrelated keys', async () => {
const store = new DiagnosticLogStore(new StorageManager());