Repository navigation
Fix file mutation lock cleanup - #8409
loopx-agent wants to merge 1 commit into
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
用户在 LoopX 打开「委派 → 全部记录」时,服务会逐批读取历史并释放用于保护这些读取的锁。
每次释放会建立一个临时声明,以保证同一时刻只有一个释放者。原来,释放者清理自己创建的声明时会重读文件;一旦声明内容损坏成无效 UTF-8,清理会中断并留下文件。改动后,释放者按创建时捕获的文件身份清理自己的声明;如果同一路径已换成另一个文件,则保留它。
在同源的八对隔离 HTTP 读回里,所有者记录读取每次从 1,696 次减为 848 次;历史结果一致,撤销权限和非法分页仍被拒绝,恢复后也能读回同一结果。
此 PR 交付声明清理和减少重复 I/O,未改变委派权限、历史排序和分页,也未改变页面呈现。 八对里五对总耗时缩短,但两组各自的中位耗时没有下降,仍需在正式入口重复验证长尾和端到端耗时。
改动思路 / Approach
锁的排他、所有权复核和跨运行时持久化仍是必要约束;用现有文件身份清理本进程声明,能移除额外解析且不用另设一套锁。 本次只改 Python 释放适配和回归测试;剩余耗时由原委派读取路径负责,正式验收须同时比较同源结果、拒绝和恢复。
核对 Python 旧实现,发现声明内容正常和内容无法识别的分支最终都调用相同的文件身份校验;读 JSON 没有决定是否删除。只捕获解码异常可以补上一个坏文件场景,却不会去掉普通路径的冗余 I/O。现有原生 TypeScript 释放端继续使用相同的磁盘契约,不需要一起改。
具体改动 / Changes
核对的提交是 817d6ec053106936169124087c665c8dbaf35212,基线是 71190b6b4ef4e146f3bf4a10d31ce61ac42fd021。远端 diff 与本地审查 diff 的稳定 patch ID 一致。
关键代码讲解
_release_effect_mutation_claim:拿到本进程独占创建时的文件身份,便直接复用受保护的删除函数;只有拿路径找回声明时,才读进程 ID 与 token。即使替换文件复制了相同的 token 和内容,其文件身份也不同,不能删除。_release_effect_mutation_lock:拿到独占声明后仍重新检查原标记的 token 和身份,匹配才改名退出活跃路径。第一次删除已退役标记成功才跳过重复删除;如果遇到短暂 I/O 失败,原回退仍会再试一次。清理临时声明的外层重试也保留。test_cross_runtime_claim_cleanup_removes_own_corrupted_claim:原先只测可解码但非法的 JSON。补上不可解码字节后基线确实失败,当前提交通过。同文件另有同内容替换和两类临时删除失败测试;去掉外层声明重试的中间版本会留下声明并触发失败。
对主干的风险 / Risks
最需防的是清理时误删接任者的声明,或删除失败后留下一把实际上已完成的锁。现有 token 与身份复核、独占声明和原子改名均保留。测试覆盖同内容替换、坏字节、活跃/过期持有者、错误 token,以及两种临时文件删除各失败一次。持续 I/O 故障及身份检查后遭外部程序改写仍由既有恢复边界处理,此改动不扩张锁模型。
本地锁测试 30 项通过、2 项平台跳过;File/SQLite 原委派 HTTP 测试 2 项通过,静态检查和本地预合并通过。全仓补充测试提前停止,不能当作全量通过。隔离配对只支持减少读取次数;生产长尾未验证。此评审按当前规则使用本地验证,未查看远端 CI。
我的整体评价 / Verdict
改动和证据足以支持这个范围内的清理修复:坏文件可恢复,替换文件与原重试仍受保护,原委派读回未变。后续再单独验证正式入口是否提速。此为作者复核,独立评审与合并资格仍待确认。
English verdict: APPROVE this bounded lock cleanup at the reviewed commit; production latency and independent approval remain open.
Goal And Delivered Outcome
Delegation history repeatedly releases shared file locks. The Python release path re-read claims whose file identity it already held, and a claim containing invalid UTF-8 could interrupt cleanup and leave the file behind.
Cleanup now uses the captured identity for an owned claim. Cleanup by pathname still checks the PID and token. Marker release still checks the token and file identity before retirement, and transient failures removing a claim or a retired marker still get a retry.
Intended base:
main.Author Declaration
model_agent, OpenAI GPT-6.loopx/file_lock.pyandloopx/control_plane/effect_runtime_io.tsat71190b6b4ef4e146f3bf4a10d31ce61ac42fd021. There is no new specification._release_effect_mutation_claim_release_effect_mutation_lock_release_effect_mutation_lockScope And Continuation
The patch changes Python file cleanup and its regression tests. It removes half the owner-record reads in a matched inventory read. End-to-end timings varied, so production latency remains a separate verification step. No new lock protocol, storage format, setting, or user action is needed.
Validation
817d6ec053106936169124087c665c8dbaf35212.finishedfor the focused checks.synthetic,authorized_private_read_only.staticpassedunitpassedtests/test_file_lock.py: 30 passed; 2 platform skips on macOS.real_entrypointpassedregression_paritypassedstaticpassedunitblockedThe results apply to the proposed commit and the isolated HTTP read. They do not establish production latency or installed behavior.
Frontend / Visual Evidence
none.Type of Change
LoopX Area
Boundary Checklist
none.