Spaces:
Running on Zero
Running on Zero
Supervised launcher: auto-respawn worker/MCP if they die
Browse files
app.py
CHANGED
|
@@ -110,8 +110,42 @@ def _spawn(module: str, port: int, name: str):
|
|
| 110 |
)
|
| 111 |
|
| 112 |
|
| 113 |
-
|
| 114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
import gradio as gr # noqa: E402 (after 'spaces' — ZeroGPU rule 1)
|
| 117 |
from web.app import app as fastapi_app # noqa: E402
|
|
|
|
| 110 |
)
|
| 111 |
|
| 112 |
|
| 113 |
+
_children = {}
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
def _supervise(specs):
|
| 117 |
+
"""Respawn dead background services forever.
|
| 118 |
+
|
| 119 |
+
The Spaces container can OOM-kill or crash the worker (it is the
|
| 120 |
+
heaviest process: torch + llama-index + chat stores). Without
|
| 121 |
+
supervision that meant "all queries fail until a manual restart";
|
| 122 |
+
with it, the launcher brings a fresh worker back within seconds.
|
| 123 |
+
"""
|
| 124 |
+
while True:
|
| 125 |
+
for key, module, port, name in specs:
|
| 126 |
+
if _listening(port):
|
| 127 |
+
continue # healthy (or handled by an older instance)
|
| 128 |
+
proc = _children.get(key)
|
| 129 |
+
if proc is not None and proc.poll() is None:
|
| 130 |
+
continue # spawned and still starting up (heavy import)
|
| 131 |
+
print(f"[LAUNCHER] {name} is DOWN - respawning on :{port}", flush=True)
|
| 132 |
+
try:
|
| 133 |
+
_children[key] = _spawn(module, port, name)
|
| 134 |
+
except Exception as spawn_err:
|
| 135 |
+
print(f"[LAUNCHER] respawn of {name} failed: {spawn_err}", flush=True)
|
| 136 |
+
time.sleep(10)
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
_supervise_specs = (
|
| 140 |
+
("worker", "Agent.worker:app", 8700, "backend worker"),
|
| 141 |
+
("mcp", "Agent.mcp_server:app", 8701, "MCP tool server"),
|
| 142 |
+
)
|
| 143 |
+
for _key, _module, _port, _name in _supervise_specs:
|
| 144 |
+
_children[_key] = _spawn(_module, _port, _name)
|
| 145 |
+
|
| 146 |
+
import threading # noqa: E402
|
| 147 |
+
|
| 148 |
+
threading.Thread(target=_supervise, args=(_supervise_specs,), daemon=True).start()
|
| 149 |
|
| 150 |
import gradio as gr # noqa: E402 (after 'spaces' — ZeroGPU rule 1)
|
| 151 |
from web.app import app as fastapi_app # noqa: E402
|