mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-12 12:47:42 +02:00
[eric] apps: a preview whose dev server never binds shows an honest failure card with retry instead of spinning Starting preview forever (Alex's report)
This commit is contained in:
@@ -497,6 +497,7 @@ def runtime_status_payload(workspace_id: str, instance: int = 1) -> dict:
|
||||
"running": rt.running,
|
||||
# 'spawned' vs 'serving': ready flips only once the primary port answered the bind poll (and un-flips when the process dies or is frozen).
|
||||
"ready": rt.ready,
|
||||
"boot_failed": bool(getattr(rt, "boot_failed", False)),
|
||||
# True when the app is served as a built bundle with no dev-server process (ENG-209).
|
||||
"serve_static": rt.serve_static,
|
||||
"port": rt.port,
|
||||
|
||||
@@ -113,6 +113,8 @@ class AppRuntime:
|
||||
self.serve_static: bool = False
|
||||
# New-mode only: flips True once something is actually listening on frontend_port (we kick off a background poll task in p_start_new_mode). frontend_url returns null until this flips, so the preview pane doesn't try to navigate to an unbound port and show a "Site can't be reached" error mid-npm-install.
|
||||
self.p_frontend_ready: bool = False
|
||||
# Set when the bind poll gave up; the status payload carries it so the card can stop spinning honestly.
|
||||
self.boot_failed = False
|
||||
# True only while a live bind-poll task owns the global vite boot lock; start() releases it otherwise.
|
||||
self.p_boot_lock_handed_off: bool = False
|
||||
# True while the process tree is SIGSTOP'd in the idle pool. A frozen vite still holds its port but can't answer it, so frontend_url must stay null while suspended (else the webview loads a dead port = the ERR_FAILED on fast app-switching).
|
||||
@@ -427,6 +429,8 @@ class AppRuntime:
|
||||
pass
|
||||
await asyncio.sleep(FRONTEND_BIND_POLL_INTERVAL)
|
||||
# Timed out; keep the runtime up (Terminal might show useful errors) but surface why the preview never appeared.
|
||||
# boot_failed reaches the CARD: the log line lands in a Terminal most users never open, so the spinner span "Starting preview" forever (Alex's report).
|
||||
self.boot_failed = True
|
||||
self.p_broadcast(LogLine(
|
||||
"runtime",
|
||||
f"[runtime] frontend did NOT bind on port {port} after "
|
||||
|
||||
@@ -315,6 +315,7 @@ async def websocket_runtime_logs(websocket: WebSocket, workspace_id: str, instan
|
||||
# The property is the one honest gate (crashed/suspended vite -> None, static -> serve URL); a duplicate running check here nulled every serve-static app's URL, whose card then waited forever on a process that never exists (the "Starting preview" wedge).
|
||||
"frontend_url": rt.frontend_url,
|
||||
"is_new_mode": rt.is_new_mode,
|
||||
"boot_failed": bool(getattr(rt, "boot_failed", False)),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user