fix: 断点丢失时 goal-resume 拒绝成 failed,阻断自动恢复空转
2026-10-29 长任务实弹:Docker goal 断点续跑在 host-state 里找 不到任务时抛 KeyError,worker 把无结论异常退出判 interrupted, 自动恢复再排队、再 KeyError,12 秒一轮空转 49 次(人工暂停 拦下,第 50 次人工续跑又烧掉),文件 32 章原样未动。 修法:host.py goal-resume 先查任务在不在 state 里,不在就打印 拒绝行、正常退出;sandbox 三处解析(本地、Docker resume、 Docker 断点)见拒绝行即判 failed 终态,不进自动恢复循环。 单测:host 缺任务拒绝不炸 + 三处解析拒绝判 failed。
This commit is contained in:
1 parent
e48b756f96
commit
a5f2e4e091
4 files changed
+138
-3
No files matched your search
@@ -0,0 +1,66 @@
|
||||
"""host.py goal-resume 断点丢失守卫:state 里没有任务时拒绝不炸。
|
||||
|
||||
2026-10-29 长任务实弹:断点续跑在 state 里找不到任务时抛
|
||||
KeyError traceback,worker 把无结论异常退出判成 interrupted,
|
||||
自动恢复再排队、再 KeyError,12 秒一轮空转到 50 次上限。
|
||||
守卫后:打印拒绝行、正常返回,state 文件不动、线程不恢复。
|
||||
"""
|
||||
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from contextlib import redirect_stdout
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT))
|
||||
|
||||
import host
|
||||
|
||||
|
||||
class FakeServer(object):
|
||||
def __init__(self):
|
||||
self.resumed = []
|
||||
|
||||
def initialize(self):
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def resume_thread(self, thread_id):
|
||||
self.resumed.append(thread_id)
|
||||
|
||||
|
||||
class GoalResumeMissingTest(unittest.TestCase):
|
||||
def test_missing_task_refuses_without_traceback(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
state_path = os.path.join(tmp, "host-state.json")
|
||||
cfg_path = os.path.join(tmp, "host-config.json")
|
||||
with open(state_path, "w", encoding="utf-8") as f:
|
||||
json.dump({"tasks": {"g": {"name": "g",
|
||||
"thread_id": "x",
|
||||
"status": "goal-running"}},
|
||||
"automations": []}, f)
|
||||
with open(cfg_path, "w", encoding="utf-8") as f:
|
||||
json.dump({}, f)
|
||||
fake = FakeServer()
|
||||
argv = ["host.py", "--state", state_path,
|
||||
"--config", cfg_path,
|
||||
"goal-resume", "--task", "missing-task"]
|
||||
out = io.StringIO()
|
||||
with mock.patch.object(sys, "argv", argv):
|
||||
with mock.patch.object(host, "Server",
|
||||
lambda **kw: fake):
|
||||
with redirect_stdout(out):
|
||||
host.main()
|
||||
self.assertIn("goal-resume 拒绝", out.getvalue())
|
||||
self.assertIn("missing-task", out.getvalue())
|
||||
self.assertEqual(fake.resumed, [])
|
||||
with open(state_path, encoding="utf-8") as f:
|
||||
saved = json.load(f)
|
||||
self.assertEqual(list(saved["tasks"].keys()), ["g"])
|
||||
Reference in new issue
Block a user