Skip to content

kernel: StreamEventLog 收缩重写非原子,写入中途崩溃会损坏整份 replay 日志 #166

Description

@RXQ6

问题

StreamEventLog.load() 在 run 数超限时原地重写唯一的历史日志文件:

writeFileSync(this.file, kept.map((e) => `${JSON.stringify(e)}\n`).join(''), 'utf8');

进程在写入中途崩溃/断电 → 文件被截断,下次启动 load 大量行进 skipped,跨重启 replay 历史丢失。这与 JsonFileStore 已经建立的"临时文件 + rename 原子替换"惯例(#109 / b67fdb6)相悖。

当前现状

代码审查基线:039c7388f855ab85f9882300c16b1898fe5955bb

  • packages/shared/src/kernel/stream-event-log.ts:108-117load() 的收缩路径直接 writeFileSync 覆盖 stream-events.jsonl
  • 同仓库 packages/shared/src/storage/json-file-store.tswrite() 早已采用 per-write tmp 文件 + rename 的原子发布模式。

期待的解决方向

  1. 收缩重写改为:先写同目录下的临时文件,再 renameSync 原子替换目标;
  2. 临时文件写失败时保持原文件不动(当前行为已如此,仅改变落盘方式);
  3. 补充/调整测试:收缩后文件内容为保留事件、目录无残留临时文件。

验证标准

  • 超限收缩后文件内容正确、无残留 .tmp 文件;
  • 临时文件写入失败时原日志保持完好;
  • 现有 stream-event-log 测试全绿。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

claimedClaimed by a contributor and currently in progress

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions