perf(session): reuse immutable persistence seed

This commit is contained in:
Magolor committed 2026-08-19 13:31:07 +08:00
1 parent 5b3a881302
commit 1c77a78d6a
2 files changed
+23 -1

No files matched your search

@@ -1170,7 +1170,7 @@ export class PersistenceCoordinator<TornMarker = unknown> {
this.live.set(session, restored)
return restored
}
const seed = session.events.map(e => structuredClone(e))
const seed = session.events
const live: LiveSessionState = {
init: Promise.resolve(),
writes: this.createWriteBehind(session, () => live.init),
@@ -180,6 +180,7 @@ class ControlledBackend implements PersistenceBackend<never> {
readonly name = 'session-persistence-controlled'
readonly store: MemoryStore = new Map()
readonly lifecycle: string[] = []
lastAppendedBatch: readonly SessionEvent[] | undefined
appendAttempts = 0
loadAttempts = 0
repairAttempts = 0
@@ -212,6 +213,7 @@ class ControlledBackend implements PersistenceBackend<never> {
}
async appendBatch(m: SessionHeader, events: readonly SessionEvent[], _isMaterialized: boolean): Promise<void> {
this.lastAppendedBatch = events
const attempt = ++this.appendAttempts
await this.beforeAppend?.(attempt)
const entry = this.store.get(m.id)
@@ -280,6 +282,26 @@ runCoordinatorContract('memory', async (): Promise<CoordinatorFixture> => {
})
describe('PersistenceCoordinator bounded writes', () => {
it('retains the immutable session seed without cloning it', async () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
const backend = new ControlledBackend()
const fiber = await ctx.plugin(Object.assign((inner: Context) => {
new PersistenceCoordinator(inner, backend)
}, { inject: ['sessions'] }))
try {
const session = ctx.sessions.create(SessionId('shared-seed'), { seed: oneTurnLog() })
const seed = session.events
await ctx.sessions.flush(session)
expect(backend.lastAppendedBatch).toBe(seed)
} finally {
await fiber.dispose()
await ctx.fiber.dispose()
}
})
it('cancels the batching deadline when live initialization rejects', async () => {
vi.useFakeTimers()
const ctx = new Context()