fix(status): /status blocked the event loop and outran its own client timeout
The backend logged 200 OK for polls the client had already timed out on. is_running() waited 2s for an Ollama that ships OFF (now 0.5s), is_available() spawned 'ollama --version' every call and that command blocks ~5s when Ollama is wedged (now cached), and both ran synchronously inside an async def, stalling the event loop on every poll while the UI polls continuously (now to_thread). Measured with Ollama's port blackholed: /status 5.89s -> 0.64s, concurrent GET / stalled -> 0.06s. Poll timeout in nexus_window.py raised 2s -> 5s for margin. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+5
-1
@@ -60,7 +60,11 @@ def _wait_for_backend(timeout: float = 40.0) -> bool:
|
|||||||
deadline = time.time() + timeout
|
deadline = time.time() + timeout
|
||||||
while time.time() < deadline:
|
while time.time() < deadline:
|
||||||
try:
|
try:
|
||||||
with urllib.request.urlopen(status_url, timeout=2) as r:
|
# 5s, not 2: /status probes Ollama, and a wedged Ollama made it
|
||||||
|
# slower than a 2s ceiling - the backend was up and answering 200
|
||||||
|
# while this loop timed out on every attempt and declared it dead.
|
||||||
|
# The server side is fixed too; this is the margin.
|
||||||
|
with urllib.request.urlopen(status_url, timeout=5) as r:
|
||||||
if r.status == 200:
|
if r.status == 200:
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
+6
-1
@@ -211,7 +211,12 @@ async def startup_event():
|
|||||||
@app.get("/status")
|
@app.get("/status")
|
||||||
async def root():
|
async def root():
|
||||||
try:
|
try:
|
||||||
status = ollama.get_status() if (ollama is not None and hasattr(ollama, "get_status")) else None
|
# to_thread, not a direct call: get_status() does blocking IO (an httpx
|
||||||
|
# request and, once, a subprocess). Awaiting it inline stalled the whole
|
||||||
|
# event loop on every poll - and the UI polls /status continuously, so
|
||||||
|
# the server froze in lockstep with its own health check.
|
||||||
|
status = (await _asyncio.to_thread(ollama.get_status)
|
||||||
|
if (ollama is not None and hasattr(ollama, "get_status")) else None)
|
||||||
except Exception:
|
except Exception:
|
||||||
status = None
|
status = None
|
||||||
return {"status": "online", "version": VERSION, "ollama": status}
|
return {"status": "online", "version": VERSION, "ollama": status}
|
||||||
|
|||||||
Reference in New Issue
Block a user