fix(worker): 终态审计带上 error,复发卡死可定位
2026-10-29 任务 A:认领后 61 秒 interrupted,但终态审计只记 task_id、自动续跑又把 error_text 覆盖掉,事后无法区分取消、 配额、host 返回 interrupted 还是其它失败;容器 --rm 后日志 也没了,根因至今无法从留存证据证明(不是 sweep:阈值 300 秒;不是外部取消:该时段无取消审计;是 worker 自己写回 interrupted,但第一轮的 error 已被第二轮 failed 覆盖)。 本批不谎称找到根因,只补可定位性:run_one 终态审计在 interrupted/failed 时 detail 带 error(截 500 字、去换行), 完成态仍只记 task_id;分段审计 worker_exec_start/error/done 已在现 main,复发时最后一段 + 终态 error 即能定位。 单测 test_final_audit_detail_carries_error:失败派发后 worker_failed 审计 detail 以 'A:' 开头且含 error 文本。
This commit is contained in:
1 parent
b306b56517
commit
f4fb4000e1
2 files changed
+36
-1
No files matched your search
@@ -481,6 +481,31 @@ class WorkerTestCase(unittest.TestCase):
|
||||
self.assertEqual(result["status"], "interrupted")
|
||||
self.assertEqual(_status(self.db_path, "A"), "interrupted")
|
||||
|
||||
def test_final_audit_detail_carries_error(self):
|
||||
# 2026-10-29 任务 A 教训:终态审计只记 task_id 时,
|
||||
# interrupted/failed 的原因事后无法区分,且自动续跑
|
||||
# 会把 error_text 覆盖掉。非完成终态的审计 detail
|
||||
# 必须带上 error,完成态仍只记 task_id。
|
||||
_insert_task(self.db_path, "A")
|
||||
|
||||
def failing(cmd):
|
||||
return SimpleNamespace(returncode=1, stdout="",
|
||||
stderr="dispatch boom xyz")
|
||||
|
||||
worker = self._worker(runner=failing)
|
||||
result = worker.run_one()
|
||||
self.assertEqual(result["status"], "failed")
|
||||
from cloud.auth import AuthStore
|
||||
store = AuthStore(self.db_path)
|
||||
try:
|
||||
entries = [e for e in store.list_audit("p1")
|
||||
if e["action"] == "worker_failed"]
|
||||
finally:
|
||||
store.conn.close()
|
||||
self.assertTrue(entries)
|
||||
self.assertTrue(entries[0]["detail"].startswith("A:"))
|
||||
self.assertIn("boom", entries[0]["detail"])
|
||||
|
||||
# -- 缺 key 门 --------------------------------------------------------
|
||||
def test_missing_key_fails_clearly_and_does_not_run(self):
|
||||
_insert_task(self.db_path, "A")
|
||||
|
||||
Reference in new issue
Block a user