fix(subagent): cascade exec session termination on /stop
cancel_by_session() only cancelled asyncio tasks, leaving child processes from exec sessions orphaned. Since each SubagentManager now owns a dedicated ExecSessionManager, terminate those sessions by owner_session_key after cancelling tasks. Add ExecSessionManager.terminate_by_owner() to kill all sessions for a given owner, and call it from cancel_by_session().
This commit is contained in:
@@ -457,6 +457,7 @@ class SubagentManager:
|
||||
t.cancel()
|
||||
if tasks:
|
||||
await asyncio.gather(*tasks, return_exceptions=True)
|
||||
await self._exec_session_manager.terminate_by_owner(session_key)
|
||||
return len(tasks)
|
||||
|
||||
async def close(self) -> None:
|
||||
|
||||
@@ -334,6 +334,19 @@ class ExecSessionManager:
|
||||
)
|
||||
return len(sessions)
|
||||
|
||||
async def terminate_by_owner(self, owner_session_key: str) -> int:
|
||||
"""Terminate all sessions owned by owner_session_key. Returns count."""
|
||||
async with self._lock:
|
||||
victims = []
|
||||
for sid, s in list(self._sessions.items()):
|
||||
if s.owner_session_key == owner_session_key:
|
||||
victims.append(self._sessions.pop(sid))
|
||||
await asyncio.gather(
|
||||
*(s.kill() for s in victims),
|
||||
return_exceptions=True,
|
||||
)
|
||||
return len(victims)
|
||||
|
||||
async def _cleanup_locked(self) -> None:
|
||||
now = time.monotonic()
|
||||
stale = [
|
||||
|
||||
Reference in New Issue
Block a user