mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-10 03:37:44 +02:00
[eric] outputs: a restart that binds clears the previous bind-timeout verdict instead of reporting boot_failed forever
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012G8kyALnPjsA7aJFmMBq3R
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
8acfe2c15e
commit
f7472a36af
@@ -231,6 +231,8 @@ class AppRuntime:
|
||||
self.p_reset_terminal_log()
|
||||
# Every boot re-decides serve mode from scratch; a stale True from the previous boot would make ready/frontend_url claim a processless app is fine after a restart that exists to spawn one.
|
||||
self.serve_static = False
|
||||
# Same for the bind-timeout verdict: a restart that then binds fine must not keep telling the card the boot failed.
|
||||
self.boot_failed = False
|
||||
if self.is_new_mode:
|
||||
# Acquire the module-level boot lock BEFORE the spawn so only one new-mode workspace is mid-bundle at a time. The lock is released by the bind-poll task the moment vite emits "frontend ready" (or its 180s timeout fires), which is the moment the next workspace can start its own vite without competing for the same CPU. See `p_await_frontend_bind` for the release.
|
||||
p_boot_lock = get_vite_boot_lock()
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
"""A bind timeout stamps boot_failed so the card stops spinning, but the flag lived on the runtime
|
||||
object forever: after one 180s timeout every later restart of the same runtime kept reporting
|
||||
boot_failed=True even while ready=True (seen live on an app card, 2026-09-02). start() now clears it."""
|
||||
|
||||
import pytest
|
||||
|
||||
from backend.apps.outputs.runtime import AppRuntime
|
||||
|
||||
|
||||
def p_rt(tmp_path) -> AppRuntime:
|
||||
ws = tmp_path / "ws"
|
||||
ws.mkdir(exist_ok=True)
|
||||
(ws / "run.sh").write_text("#!/bin/bash\n")
|
||||
return AppRuntime(workspace_id="ws-boot-failed", workspace_path=str(ws))
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_a_restart_that_boots_clears_the_previous_bind_timeout(tmp_path, monkeypatch):
|
||||
rt = p_rt(tmp_path)
|
||||
rt.boot_failed = True
|
||||
|
||||
async def p_fake_spawn() -> bool:
|
||||
return True
|
||||
|
||||
monkeypatch.setattr(rt, "p_start_new_mode", p_fake_spawn)
|
||||
assert await rt.start() is True
|
||||
assert rt.boot_failed is False, "a boot that spawned fine must not keep telling the card the previous one failed"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_an_already_running_runtime_keeps_its_verdict(tmp_path, monkeypatch):
|
||||
rt = p_rt(tmp_path)
|
||||
rt.boot_failed = True
|
||||
monkeypatch.setattr(type(rt), "running", property(lambda self: True))
|
||||
assert await rt.start() is True
|
||||
assert rt.boot_failed is True, "start() on a live runtime is a no-op and must not rewrite state"
|
||||
Reference in New Issue
Block a user