refactor: prune dead session surfaces
This commit is contained in:
@@ -26,7 +26,7 @@ import {
|
||||
SessionPersistence, PersistenceCoordinator,
|
||||
type PersistenceBackend, type StoredPrefix,
|
||||
} from '@deepseek-ai/dsh-session-persistence'
|
||||
import type { Session, SessionEvent, SessionId, SessionHeader } from '@deepseek-ai/dsh-session'
|
||||
import type { SessionEvent, SessionId, SessionHeader } from '@deepseek-ai/dsh-session'
|
||||
import {
|
||||
encodeSegment, eventLine, logPath, parseHeaderMeta, scanLog, sessionDir, toHeaderLine,
|
||||
} from './format.ts'
|
||||
@@ -108,14 +108,6 @@ export class SessionPersistenceJsonl extends SessionPersistence implements Persi
|
||||
// this same method; routing it through the coordinator would recurse. Defined
|
||||
// once, in the "PersistenceBackend hooks" section.
|
||||
|
||||
/**
|
||||
* The per-session init promises, exposed for white-box tests that await a
|
||||
* specific session's onCreated (there is no public API to await one init).
|
||||
*/
|
||||
get inits(): Map<Session, Promise<void>> {
|
||||
return this.coordinator.inits
|
||||
}
|
||||
|
||||
// --- PersistenceBackend hooks (the file-bytes storage primitives) ---
|
||||
|
||||
/** Read a stored prefix by id across ALL cwd buckets (cwd unknown). */
|
||||
|
||||
@@ -496,12 +496,11 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
// the Session OBJECT, so this gets its OWN onCreated (not A's stale promise)
|
||||
// — which detects the on-disk collision and rejects, rather than silently
|
||||
// appending the new session's events onto A's log under a stale cursor.
|
||||
const backend = ctx.sessionPersistence as unknown as { inits: Map<Session, Promise<void>> }
|
||||
let b!: Session
|
||||
await ctx.plugin(Object.assign((inner: Context) => {
|
||||
b = inner.sessions.create(SessionId('reuse'), { meta: { cwd: '/a' } })
|
||||
}, { inject: ['sessions'] }))
|
||||
await expect(backend.inits.get(b)).rejects.toThrow(/already bound to a different live session|already has a persisted log on disk/)
|
||||
await expect(ctx.sessions.flush(b)).rejects.toThrow(/already bound to a different live session|already has a persisted log on disk/)
|
||||
})
|
||||
|
||||
it('a NO-CWD live session does NOT cross-cwd-adopt a same-id log from a real cwd bucket (loadLive is scope-exact)', async () => {
|
||||
@@ -523,12 +522,11 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
const ctx2 = new Context()
|
||||
await ctx2.plugin(SessionStore)
|
||||
await ctx2.plugin(SessionPersistenceJsonl, { root })
|
||||
const backend = ctx2.sessionPersistence as unknown as { inits: Map<Session, Promise<void>> }
|
||||
let b!: Session
|
||||
await ctx2.plugin(Object.assign((inner: Context) => {
|
||||
b = inner.sessions.create(SessionId('x')) // no cwd
|
||||
}, { inject: ['sessions'] }))
|
||||
await expect(backend.inits.get(b)).rejects.toThrow(/already has a persisted log on disk/)
|
||||
await expect(ctx2.sessions.flush(b)).rejects.toThrow(/already has a persisted log on disk/)
|
||||
|
||||
// The "/w" log is untouched — no no-cwd events were grafted onto it, and no
|
||||
// `_no-cwd` log for "x" was created.
|
||||
@@ -545,7 +543,6 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
await ctx.sessionPersistence.append(SessionId('divergent'), oneTurnLog())
|
||||
await ctx.sessionPersistence.load(SessionId('divergent'))
|
||||
|
||||
const backend = ctx.sessionPersistence as unknown as { inits: Map<Session, Promise<void>> }
|
||||
// A seed that keeps every seq/type/time but mutates a payload must NOT be
|
||||
// accepted as "the same session" — otherwise drain filters those seqs as
|
||||
// already persisted and the divergent payload is silently lost.
|
||||
@@ -556,7 +553,7 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
await ctx.plugin(Object.assign((inner: Context) => {
|
||||
bad = inner.sessions.create(SessionId('divergent'), { seed: tampered, meta: { cwd: '/a' } })
|
||||
}, { inject: ['sessions'] }))
|
||||
await expect(backend.inits.get(bad)).rejects.toThrow(/do not match this live session|already has a persisted log/)
|
||||
await expect(ctx.sessions.flush(bad)).rejects.toThrow(/do not match this live session|already has a persisted log/)
|
||||
})
|
||||
|
||||
it('a second live session reusing a bound id is rejected', async () => {
|
||||
@@ -569,12 +566,11 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
for (const s of ctx.sessions.list()) await ctx.parallel('session/flush', s)
|
||||
await firstFiber.dispose()
|
||||
|
||||
const backend = ctx.sessionPersistence as unknown as { inits: Map<Session, Promise<void>> }
|
||||
let second!: Session
|
||||
await ctx.plugin(Object.assign((inner: Context) => {
|
||||
second = inner.sessions.create(SessionId('bound'), { meta: { cwd: '/a' } })
|
||||
}, { inject: ['sessions'] }))
|
||||
await expect(backend.inits.get(second))
|
||||
await expect(ctx.sessions.flush(second))
|
||||
.rejects.toThrow(/already bound to a different live session|already has a persisted log|do not match/)
|
||||
})
|
||||
|
||||
@@ -610,12 +606,11 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
await ctx2.plugin(SessionStore)
|
||||
await ctx2.plugin(SessionPersistenceJsonl, { root })
|
||||
await writeFile(sessionDir(root, cwd), 'x') // bucket path is now a FILE
|
||||
const backend = ctx2.sessionPersistence as unknown as { inits: Map<Session, Promise<void>> }
|
||||
let s!: Session
|
||||
await ctx2.plugin(Object.assign((inner: Context) => {
|
||||
s = inner.sessions.create(SessionId('exists-fault'), { meta: { cwd } })
|
||||
}, { inject: ['sessions'] }))
|
||||
await expect(backend.inits.get(s)).rejects.toThrow(/ENOTDIR/)
|
||||
await expect(ctx2.sessions.flush(s)).rejects.toThrow(/ENOTDIR/)
|
||||
await ctx2.fiber.dispose()
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user