Double-start guard: launching marker, probe-and-adopt, fresh-dir relaunch; skip unreachable terminals per tick
Before the launch call the planned run (run id, terminal, handle, bookkeeping) is saved as a launching marker. If the launch call fails or agentd dies before recording the run, the next tick probes the run directory (exit.txt / launch.pid / pid.txt): evidence -> adopt the run; nothing -> relaunch with the same run id in <run_id>-r2 (-r3 ...); probe unreachable -> keep the marker, which holds the terminal slot. Transports refuse to clean a run directory holding a pid file. A terminal whose relay fails is skipped for the rest of the tick (heartbeat.down) while other terminals carry on.
This commit is contained in:
@@ -120,3 +120,30 @@ class StoreTest(unittest.TestCase):
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
|
||||
class GuardTest(unittest.TestCase):
|
||||
def test_local_clean_refuses_dir_with_pid_file(self):
|
||||
from agentd.transports import TransportError
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
t = LocalTransport(Config(config_data()), "oregon")
|
||||
(Path(tmp) / "prompt.md").write_text("x")
|
||||
t.mkdir(tmp, clean=True)
|
||||
self.assertEqual(t.probe(tmp, ("exit.txt", "pid.txt")), [])
|
||||
(Path(tmp) / "pid.txt").write_text("1")
|
||||
with self.assertRaises(TransportError):
|
||||
t.mkdir(tmp, clean=True)
|
||||
self.assertEqual(t.probe(tmp, ("exit.txt", "pid.txt")), ["pid.txt"])
|
||||
|
||||
def test_windows_probe_and_clean_guard(self):
|
||||
from agentd.transports import TransportError
|
||||
cfg = config.load(ROOT / "config" / "agentd.example.yaml")
|
||||
t = WindowsWarpgateTransport(cfg, "win10")
|
||||
scripts = []
|
||||
t.ps = lambda s, timeout=150: (scripts.append(s), "PROBE=launch.pid,pid.txt\n")[1]
|
||||
self.assertEqual(t.probe("C:\\r\\GW-1-1", ("exit.txt", "launch.pid", "pid.txt")), ["launch.pid", "pid.txt"])
|
||||
self.assertIn("Join-Path $d $_", scripts[-1])
|
||||
t.ps = lambda s, timeout=150: (scripts.append(s), "HASPID\n")[1]
|
||||
with self.assertRaises(TransportError):
|
||||
t.mkdir("C:\\r\\GW-1-1", clean=True)
|
||||
self.assertIn("'pid.txt'", scripts[-1])
|
||||
|
||||
Reference in New Issue
Block a user