fix(session-mechanism/graph): 并发写不丢状态,测试不再被批量删除守卫拦
- graphctl.py 并发修复
· 临时名原来固定成 graph.json.tmp ⇒ 两进程同时写直接撞 PermissionError(桌面实测第 14 条)
· 新增 _update():读最新状态 → 重放本次变更 → 原子替换 → 回读核对 _rev,
被覆盖则重读重做(最多 3 次),仍失败就报错退出
· 修掉更隐蔽的一层:后写的整份覆盖前写会让节点状态静默消失
· start / report 改为走 _update,业务校验放在 mutate 内
- test_graphctl.py
· 每例只新建自己的目录、跑完不删,整轮收尾清一次 ⇒ 不再触发沙箱「批量删除」守卫
(此前 49 条里 20 条报 ERROR,全部是本机策略拦清理,用例本身零失败)
· 新增 T9_Concurrency 三个用例:并发开工、并发回报、版本号每次写都前进
· 49 → 52 条,实跑 Ran 52 tests OK(13 s)
- README:补「并发写是怎么保证的」三层说明,测试数与用时更新
This commit is contained in:
1 parent
4866ad8d37
commit
42a130e4f2
3 files changed
+136
-26
No files matched your search
@@ -85,9 +85,19 @@
|
||||
|
||||
python graph/test_graphctl.py -v
|
||||
|
||||
全绿应看到 `Ran 49 tests ... OK`,用时 20 秒上下(每条用例起一次子进程)。
|
||||
全绿应看到 `Ran 52 tests ... OK`,用时 15 秒上下(每条用例起一次子进程)。
|
||||
|
||||
测试只往临时目录写:`<GRAPH_TEST_TMP>/graph-test-<pid>/<用例名>`,默认 `GRAPH_TEST_TMP` = `AIProject/ai1net-dsh-server/tmp`,由每条用例的 `tearDown` + 进程退出的 `atexit` 兜底删除。想换落点就设环境变量 `GRAPH_TEST_TMP`。
|
||||
测试只往临时目录写:`<GRAPH_TEST_TMP>/graph-test-<pid>/<用例名>`,默认 `GRAPH_TEST_TMP` = `AIProject/ai1net-dsh-server/tmp`。每条用例只**新建**自己的目录、跑完不删,整轮收尾由 `tearDownModule` 清一次;这样一次跑下来新建几十个文件、不触发本机沙箱的「批量删除」守卫(那个守卫一次删满 50 个文件就会拦,曾让 20 条用例报 ERROR,而用例本身零失败)。想换落点就设环境变量 `GRAPH_TEST_TMP`。
|
||||
|
||||
## 五之二、并发写是怎么保证的
|
||||
|
||||
两个进程可以同时对同一张图动手(比如两个节点同时开工),做法是三层:
|
||||
|
||||
1. 临时文件名带进程号与随机数,两个进程写字不会撞同一个名字(早期版本用固定名 `graph.json.tmp`,并发时直接报 `PermissionError`)。
|
||||
2. 每次写都先读最新磁盘状态、在它上面重放本次变更,再原子替换——避免「后写的整份覆盖前写的」导致节点状态静默消失。
|
||||
3. 图里带 `_rev` 版本号:写完回读核对,发现自己不是最新一版就重读重做,连续三次仍被覆盖才报错退出(要的是「宁可报错,也不静默丢状态」)。
|
||||
|
||||
这条路径由 `T9_Concurrency` 的三个用例守着:并发开工两个节点、并发回报两个节点、版本号每次写都前进。
|
||||
|
||||
清残留在本机是常态:跑完后 `tmp/` 下偶尔还能看到 `graph-test-<pid>/`(进程内已确认删空,是本机沙箱在进程退出后把删除路径又放回来了,与测试代码无关)。一条命令清掉:
|
||||
|
||||
|
||||
Reference in new issue
Block a user