Rust in Everything
基于 loom 0.7.2

设了 LOOM_CHECKPOINT_FILE,失败后文件却不存在;或者测试只跑了 1 轮就通过

主线位置:主线 1 的调试面。checkpoint 文件就是序列化的 Path,写入和载入都在 Builder::check 的主循环里(checkpoint、日志与位置)。

flowchart TB
  start["启动:文件存在?"] -->|存在| ld["载入,从那条路径开始"]
  start -->|不存在| r["从头开始"]
  ld --> loop
  r --> loop["第 i 轮"]
  loop --> w{"i % interval == 0"}
  w -->|是| st["写文件"]
  w -->|否| run["跑;失败就 panic 穿出,不额外写"]
  st --> run
  run --> loop
  run -->|跑完| keep["文件留在磁盘上,下次启动还会载入"]

三种现象

现象原因实测
照文档设了 LOOM_CHECKPOINT_FILE,测试在前几轮失败,文件不存在只在第 interval(默认 20 000)的整数倍轮开始前写,失败时不写E3:第 3 个交错失败的模型,默认间隔下没有文件
修好 bug 再跑,测试通过得特别快上次留下的文件存在就载入,从那条路径接着走90 个交错的模型,第三次运行只跑 1 轮就「通过」
没开 checkpoint feature,设了变量,小模型照常通过不存在的文件不会去读,不到整点不会去写,两个 panic 都碰不到E3 反向:4 个交错,通过,没有任何提示

数据都来自 checkpoint、日志与位置(exp-loom/survey/tests/checkpoint2.rs、exp-loom/usage/tests/stale.rs、exp-loom/no-checkpoint)。

源码出处

  • 载入:文件存在就 load_execution_path(model.rs:152-157)。
  • 写入:i % self.checkpoint_interval == 0 时 store_execution_path(164-178 行),写的是这一轮即将走的路径。
  • 没开 feature:两个函数都是 panic!("not compiled with checkpoint feature")(267-278 行),只有真的走到上面两个调用点才触发。

文档的三步法(lib.rs:192-249)第 1 步「生成 checkpoint」,只有失败发生在第 20 000 个交错之后才会生成文件;第 2 步也不会「第一个交错就失败」,而是从最近的整点续跑。

怎么改

  1. 依赖里给 loom 开 checkpoint feature(tokio 就开了 checkpoint 和 futures)。
  2. 失败来得早:直接 LOOM_CHECKPOINT_FILE=f.json LOOM_CHECKPOINT_INTERVAL=1 跑一次,失败时文件就是那一轮的路径;再加 LOOM_LOG=trace LOOM_LOCATION=1 用同一个文件重跑,第 1 个交错就失败,日志只有这一轮。
  3. 失败来得晚:先只设 LOOM_CHECKPOINT_FILE 跑出一个离失败不到 20 000 轮的起点,再加 INTERVAL=1 续跑到失败。E3 的晚失败模型第 54 301 个交错失败,第一步留下第 40 000 轮的文件,第二步在第 14 302 个交错失败。
  4. 修完删文件。 不要把 LOOM_CHECKPOINT_FILE 写进 CI 的环境变量;在测试里设置时,用每次运行都不同的临时路径。

小结

  • 文件只在整 interval 轮写,默认 20 000;早失败不留文件,晚失败留下最近整点的路径。
  • 文件存在就从那里开始:残留文件让 90 个交错的模型只跑 1 轮就报通过。
  • 没开 checkpoint feature,小模型静默忽略设置;到整点或文件存在时 panic「not compiled with checkpoint feature」。
  • 能用的流程:INTERVAL=1 存下精确路径 → 加日志重放 → 修完删文件。

💬 关联讨论

发起讨论
加载中...