fix(terminal): prevent double session creation, restore sessions on reload
Three fixes for multi-session terminal bugs: 1. Race-condition double creation: The auto-create effect fired twice because loadSessions returned 0 while an earlier createSession was still in flight. Added hasAutoCreated guard ref to ensure only one auto-create happens. 2. Page reload spawns new sessions: After server restart, list_terminal_sessions filtered out DB-only sessions (no in-memory counterpart), so the frontend thought no sessions existed and auto-created new ones. Reverted the filter so DB rows are always returned. The WebSocket handler now restores the in-memory session from the DB row on demand when connecting. 3. No input after connection: The backend _read_loop would break on any send error, causing asyncio.wait to cancel the _write_loop. Made _read_loop retry up to 3 times before giving up, preventing transient send errors from killing input handling. Quality gates: pytest (15/15 passed), tsc clean
This commit is contained in:
@@ -131,6 +131,7 @@ class TerminalManager:
|
||||
container_id: str,
|
||||
startup_command: str | None = None,
|
||||
name: str | None = None,
|
||||
session_id: str | None = None,
|
||||
) -> TerminalSession:
|
||||
"""Create a new terminal session for an instance.
|
||||
|
||||
@@ -159,7 +160,8 @@ class TerminalManager:
|
||||
instance_id_str, self.MAX_SESSIONS_PER_INSTANCE
|
||||
)
|
||||
|
||||
session_id = str(uuid.uuid4())
|
||||
if session_id is None:
|
||||
session_id = str(uuid.uuid4())
|
||||
session = TerminalSession(
|
||||
session_id=session_id,
|
||||
instance_id=instance_id,
|
||||
@@ -172,7 +174,7 @@ class TerminalManager:
|
||||
key = (instance_id_str, session_id)
|
||||
self._sessions[key] = session
|
||||
|
||||
# Fire-and-forget DB insert
|
||||
# Fire-and-forget DB insert (skip if row already exists)
|
||||
asyncio.create_task(
|
||||
self._insert_db_session_row(session_id, instance_id, session.name)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user