docs(jsonl): align restore slice interval
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-05-large-session-jsonl-restore-pipeline.md
|
||||
2026-08-05-large-session-jsonl-restore-pipeline.md: 82ef45ab91408a96b6ce831a28187fe50506dfdd
|
||||
2026-08-05-large-session-jsonl-restore-pipeline.zh.md: b7514df34ffeb45276990911bb2a18960b6b9303
|
||||
2026-08-05-large-session-jsonl-restore-pipeline.md: eab53c683880ef7095233ed8122e532eb5add547
|
||||
2026-08-05-large-session-jsonl-restore-pipeline.zh.md: 039e0c193179677b57e742d55f4c7df6bdff852f
|
||||
|
||||
@@ -20,7 +20,7 @@ The structural Zstandard scanner identifies complete frame ranges before decodin
|
||||
|
||||
`ZstdFrameDecoder` gives the reader one lifecycle for interchangeable synchronous implementations. The preferred implementation probes the supported Node 22, 24, and 26 stream shape, reuses one private native decoder context and scratch buffer across all complete frames, and closes it once. If that private shape is unavailable, the factory selects a public `zstdDecompressSync` implementation with the same iterator and checksum-error contract. A yielded scratch view is consumed before the iterator advances.
|
||||
|
||||
After approximately one second of accumulated frame work, the asynchronous reader yields at the next frame boundary and observes cancellation before continuing. A single frame remains an indivisible synchronous operation. Complete frames require end-of-frame and checksum validation; only a structurally incomplete final frame uses the existing prefix decoder for recovery.
|
||||
After approximately 500 ms of accumulated frame work, the asynchronous reader yields at the next frame boundary and observes cancellation before continuing. A single frame remains an indivisible synchronous operation. Complete frames require end-of-frame and checksum validation; only a structurally incomplete final frame uses the existing prefix decoder for recovery.
|
||||
|
||||
### Incremental JSONL scanning
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Zstandard 结构扫描器会在解码前识别完整帧范围。系统单独解
|
||||
|
||||
`ZstdFrameDecoder` 为可互换的同步实现提供统一生命周期。首选实现会探测受支持 Node 22、24 与 26 的流结构,在所有完整帧之间复用一个私有原生解码上下文和临时缓冲区,最后只关闭一次。如果私有结构不可用,工厂会选择使用公共 `zstdDecompressSync` 的实现,并保持相同的迭代器和校验和错误契约。迭代器产出的临时视图会在进入下一次迭代前被消费。
|
||||
|
||||
累计帧处理时间约达 1 秒后,异步读取器会在下一帧边界让出事件循环,并在继续前观察取消信号。单个帧仍是不可分割的同步操作。完整帧必须通过帧结束与校验和验证;只有结构上不完整的最终帧才使用既有前缀解码器进行恢复。
|
||||
累计帧处理时间约达 500 ms 后,异步读取器会在下一帧边界让出事件循环,并在继续前观察取消信号。单个帧仍是不可分割的同步操作。完整帧必须通过帧结束与校验和验证;只有结构上不完整的最终帧才使用既有前缀解码器进行恢复。
|
||||
|
||||
### 增量 JSONL 扫描
|
||||
|
||||
|
||||
@@ -433,7 +433,7 @@ describe('SessionPersistenceJsonl: default Zstandard encoding', () => {
|
||||
await expect(ctx.sessionPersistence.load(header.id)).rejects.toThrow(/frame at byte .* failed validation/)
|
||||
})
|
||||
|
||||
it('stops multi-frame inspection when cancellation arrives at a one-second slice boundary', async () => {
|
||||
it('stops multi-frame inspection when cancellation arrives at a slice deadline', async () => {
|
||||
const root = await freshRoot()
|
||||
const ctx = await mount(root)
|
||||
const header = meta('cancel-zstd-frames')
|
||||
@@ -444,14 +444,14 @@ describe('SessionPersistenceJsonl: default Zstandard encoding', () => {
|
||||
const controller = new AbortController()
|
||||
const reason = new Error('cancel after Zstandard decode starts')
|
||||
const reader = ctx.sessionPersistence as unknown as ZstdReaderInternals
|
||||
vi.spyOn(performance, 'now').mockReturnValueOnce(0).mockReturnValue(1001)
|
||||
vi.spyOn(performance, 'now').mockReturnValueOnce(0).mockReturnValue(501)
|
||||
const pending = reader.readZstdPrefix(stream, controller.signal)
|
||||
queueMicrotask(() => { controller.abort(reason) })
|
||||
|
||||
await expect(pending).rejects.toBe(reason)
|
||||
})
|
||||
|
||||
it('continues decoding every frame after a one-second slice yields', async () => {
|
||||
it('continues decoding every frame after a slice deadline yields', async () => {
|
||||
const root = await freshRoot()
|
||||
const ctx = await mount(root)
|
||||
const header = meta('yield-zstd-frames')
|
||||
@@ -462,7 +462,7 @@ describe('SessionPersistenceJsonl: default Zstandard encoding', () => {
|
||||
)))
|
||||
const stream = Buffer.concat([headerFrame, ...eventFrames])
|
||||
const reader = ctx.sessionPersistence as unknown as ZstdReaderInternals
|
||||
vi.spyOn(performance, 'now').mockReturnValueOnce(0).mockReturnValue(1001)
|
||||
vi.spyOn(performance, 'now').mockReturnValueOnce(0).mockReturnValue(501)
|
||||
|
||||
const prefix = await reader.readZstdPrefix(stream)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user