Просмотр исходного кода

test(session): synchronize shared migration cancellation waiters

Tianyi Cui 3 недель назад
Родитель
Сommit
eaae3502ae
1 измененных файлов с 23 добавлено и 10 удалено
  1. 23 10
      packages/session/session-persistence-jsonl/tests/jsonl.spec.ts

+ 23 - 10
packages/session/session-persistence-jsonl/tests/jsonl.spec.ts

@@ -792,18 +792,31 @@ describe('JsonlSessionPersistence: immutable format generations', () => {
     readTally.enabled = true
     const controller = new AbortController()
     const reason = new Error('first historical waiter cancelled')
+    const secondController = new AbortController()
+    const firstListener = vi.spyOn(controller.signal, 'addEventListener')
+    const secondListener = vi.spyOn(secondController.signal, 'addEventListener')
 
     const first = ctx.sessionPersistence.open(header.id, 'read', { signal: controller.signal })
-    const second = ctx.sessionPersistence.open(header.id, 'read')
-    await pause.entered
-    await scheduler.yield()
-    controller.abort(reason)
-    await expect(first).rejects.toBe(reason)
-    pause.release()
-    const handle = await second
-    expect((await handle.read()).events).toEqual([])
-    expect(readTally.bySuffix.get(sourcePath)).toBe(1)
-    await handle.close()
+    const second = ctx.sessionPersistence.open(header.id, 'read', { signal: secondController.signal })
+    try {
+      await pause.entered
+      // Both callers must be waiting on preparation, not still discovering the source.
+      await vi.waitFor(() => {
+        expect(firstListener).toHaveBeenCalledWith('abort', expect.any(Function), { once: true })
+        expect(secondListener).toHaveBeenCalledWith('abort', expect.any(Function), { once: true })
+      })
+      controller.abort(reason)
+      await expect(first).rejects.toBe(reason)
+      pause.release()
+      const handle = await second
+      expect((await handle.read()).events).toEqual([])
+      expect(readTally.bySuffix.get(sourcePath)).toBe(1)
+    } finally {
+      pause.release()
+      for (const outcome of await Promise.allSettled([first, second])) {
+        if (outcome.status === 'fulfilled') await outcome.value.close()
+      }
+    }
   })
 
   it('cancels shared historical preparation after its last waiter leaves', async () => {