feat(jobs): 本地结果 GC —— 终态 job 保留 48h 后自动清理(不重启) - #22
Merged
Merged
Conversation
背景:job 结果(含逐 token logprob 三元组)写在 SMG_JOBS_DIR,此前**只有显式
DELETE /v1/control/jobs/{id}** 一条清理路径 —— 没有人删就永久堆积。实测 1021:
69 个 job / 954 MB,其中单个 job 目录 159 MB(job.json 83 MB、结果文件 8 MB),
近 24h 增量 923 MB;磁盘迟早被吃满。
本次加入基础 GC:
* `SMG_JOBS_RETENTION_HOURS`(默认 **48**,支持小数;**0 = 关闭 GC**)
—— 超过保留期、且**已终态**的 job 目录被删除;
* `SMG_JOBS_GC_INTERVAL_SECS`(默认 1800)—— 后台扫描周期;启动时立即扫一次,
回收停机期间积压的旧数据;
* 判定"最后活动时间"取 job 目录内文件的**最新 mtime**:job.json 每次状态变更都会
重写、task_*.json 随任务完成落盘,因此该时间跟随真实进度;
* 安全性:**queued / running 的 job 永不删除**(内存中状态优先于文件年龄);
未被内存登记的历史目录同样按年龄回收;删除会打日志(含释放体积),并把内存
注册表项 + 每任务 live flag/progress/partial 一并清掉(复用 remove_job);
* 兼容:GC 只动本地文件与内存状态,不触碰引擎 / LoRA / 正在执行的请求。
实现:
* `JobManager.retention: Option<Duration>`;`new()` 从 env 取,新增私有
`build(..., retention)` 便于测试注入;
* `gc_once()`(一次扫描,返回删除数)+ `spawn_gc_task()`(`tokio::time::interval`
循环)+ 辅助 `newest_mtime()` / `dir_size()`;
* `server.rs`:`recover_from_disk()` 之后 `spawn_gc_task()`;GC 自己打一行配置日志
(`jobs: gc enabled (retention 48.0h, idempotent scan every 1800s)`)。
单测 +4(`cargo test --lib control_plane::jobs::`):
1. 过期终态删除、running 保留、未过期保留(同时验证内存条目一起清);
2. `SMG_JOBS_RETENTION_HOURS=0`(retention=None)时一个都不删;
3. 未登记的历史目录被回收 + 内存注册表项被删;
4. 辅助函数(最后活动时间 / 目录体积)行为正确。
文档:`docs/agent/training-jobs-api.md`(保留期条目改为"48h + GC 语义",运维变量
补上两个 env 与判据日志样例)。
**未部署**:本 PR 只改代码,不重启、不动生产(避免影响在跑的训练)。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
这个 PR 做什么
给训练 job 加基础本地 GC:终态 job 的结果在磁盘上保留 48 小时后自动清理。此前只有显式
DELETE /v1/control/jobs/{id}一条清理路径,不删就永久堆积。只改代码,不重启、不动生产(避免影响在跑的训练)。
1. 为什么
1021 实测(
/root/smg-jobs):job.json一个文件 83 MB + 结果文件 8 MB/任务)delete_job→remove_job(jobs.rs:1129),无任何 TTL/GC2. 本次实现
SMG_JOBS_RETENTION_HOURSSMG_JOBS_GC_INTERVAL_SECSqueued/running(内存状态优先于文件年龄)job.json每次状态变更重写、task_*.json随任务完成落盘 → 跟随真实进度)remove_job:目录 + 内存注册表项 + 每任务 live flag/progress/partial 一并清jobs: gc removed job_xxx (idle 52.1h > retention 48.0h, freed 91.2 MB)jobs: gc enabled (retention 48.0h, idempotent scan every 1800s)边界:GC 只动本地文件与内存状态 —— 不触碰引擎、LoRA、正在执行的请求。
3. 实现要点
JobManager { retention: Option<Duration> };new()从 env 读取,新增私有build(..., retention)便于测试注入;gc_once():一次扫描,返回删除数;spawn_gc_task():tokio::time::interval循环;newest_mtime(dir)(文件优先,目录 mtime 兜底)、dir_size(dir)(递归体积,用于日志/核算);server.rs:recover_from_disk()之后调用spawn_gc_task()。4. 验证
新增 4 个用例覆盖:
running→ 保留;未过期 → 保留(并验证内存条目一起清);SMG_JOBS_RETENTION_HOURS=0(retention=None)→ 一个都不删;5. 文档
docs/agent/training-jobs-api.md:SMG_JOBS_RETENTION_HOURS/SMG_JOBS_GC_INTERVAL_SECS与判据日志样例。6. 上线方式(本 PR 不含)
需要一次 smg 重建 + 重启才生效(重启会打断在跑 job;磁盘结果会在启动时恢复)。待批准后再做。
CI States
Latest PR Test (Base): ✅ Run #34921492363
Latest PR Test (Extra): ❌ Run #34921492177