fix: improve terminal robustness with exponential backoff and better keepalive
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 3m11s
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 3m11s
- Backend: Add 10s connection timeout, improve SSH keepalive (15s × 8 retries) - Backend: Add detailed error logging for debugging - Frontend: Implement exponential backoff (1s → 30s max) instead of fixed 2s - Frontend: Reduce heartbeat to 12s (within 15s SSH keepalive window) - Frontend: Reset reconnect counter on successful connection - Frontend: Fix race condition in auth recovery after manual close
This commit is contained in:
@@ -125,13 +125,22 @@ async def ws_endpoint(websocket: WebSocket, host: str = Query("nas"), token: str
|
||||
|
||||
h = HOSTS[host]
|
||||
try:
|
||||
conn = await asyncssh.connect(
|
||||
h["host"], username=h["user"],
|
||||
client_keys=[h["key"]], known_hosts=_known_hosts,
|
||||
keepalive_interval=30,
|
||||
keepalive_count_max=3,
|
||||
conn = await asyncio.wait_for(
|
||||
asyncssh.connect(
|
||||
h["host"], username=h["user"],
|
||||
client_keys=[h["key"]], known_hosts=_known_hosts,
|
||||
keepalive_interval=15,
|
||||
keepalive_count_max=8,
|
||||
),
|
||||
timeout=10.0
|
||||
)
|
||||
except Exception:
|
||||
except asyncio.TimeoutError:
|
||||
logger.error("SSH connection to %s timed out after 10s", host)
|
||||
await _release_session(session_id)
|
||||
await websocket.close(code=1011, reason="SSH connection timeout")
|
||||
return
|
||||
except Exception as e:
|
||||
logger.error("SSH connection to %s failed: %s", host, e)
|
||||
await _release_session(session_id)
|
||||
await websocket.close(code=1011, reason="SSH connection failed")
|
||||
return
|
||||
@@ -149,8 +158,12 @@ async def ws_endpoint(websocket: WebSocket, host: str = Query("nas"), token: str
|
||||
if not data:
|
||||
break
|
||||
await websocket.send_bytes(data)
|
||||
except (asyncssh.Error, asyncio.CancelledError):
|
||||
except asyncssh.Error as e:
|
||||
logger.warning("SSH read error for %s: %s", host, e)
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
except Exception as e:
|
||||
logger.error("Unexpected error reading SSH for %s: %s", host, e)
|
||||
|
||||
read_task = asyncio.create_task(read_ssh())
|
||||
|
||||
@@ -169,8 +182,8 @@ async def ws_endpoint(websocket: WebSocket, host: str = Query("nas"), token: str
|
||||
if msg["text"] == "__ping__":
|
||||
continue
|
||||
process.stdin.write(msg["text"].encode())
|
||||
except Exception:
|
||||
pass
|
||||
except Exception as e:
|
||||
logger.info("WebSocket receive loop ended for %s: %s", host, e)
|
||||
finally:
|
||||
read_task.cancel()
|
||||
process.close()
|
||||
|
||||
Reference in New Issue
Block a user