mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-06 17:38:35 +00:00
fix(exec): retain failed owner session cleanup
This commit is contained in:
parent
ebf1ef5cab
commit
80085085d9
@ -341,10 +341,25 @@ class ExecSessionManager:
|
|||||||
for sid, s in list(self._sessions.items()):
|
for sid, s in list(self._sessions.items()):
|
||||||
if s.owner_session_key == owner_session_key:
|
if s.owner_session_key == owner_session_key:
|
||||||
victims.append(self._sessions.pop(sid))
|
victims.append(self._sessions.pop(sid))
|
||||||
await asyncio.gather(
|
results = await asyncio.gather(
|
||||||
*(s.kill() for s in victims),
|
*(s.kill() for s in victims),
|
||||||
return_exceptions=True,
|
return_exceptions=True,
|
||||||
)
|
)
|
||||||
|
failures = [
|
||||||
|
(session, result)
|
||||||
|
for session, result in zip(victims, results, strict=True)
|
||||||
|
if isinstance(result, BaseException)
|
||||||
|
]
|
||||||
|
if failures:
|
||||||
|
async with self._lock:
|
||||||
|
for session, _ in failures:
|
||||||
|
self._sessions[session.session_id] = session
|
||||||
|
if len(failures) == 1:
|
||||||
|
raise failures[0][1]
|
||||||
|
raise BaseExceptionGroup(
|
||||||
|
"failed to terminate exec sessions by owner",
|
||||||
|
[result for _, result in failures],
|
||||||
|
)
|
||||||
return len(victims)
|
return len(victims)
|
||||||
|
|
||||||
async def _cleanup_locked(self) -> None:
|
async def _cleanup_locked(self) -> None:
|
||||||
|
|||||||
@ -679,6 +679,29 @@ def test_terminate_by_owner_returns_zero_for_no_match(tmp_path):
|
|||||||
asyncio.run(run())
|
asyncio.run(run())
|
||||||
|
|
||||||
|
|
||||||
|
def test_terminate_by_owner_retains_failed_sessions():
|
||||||
|
async def run() -> None:
|
||||||
|
manager = ExecSessionManager()
|
||||||
|
session = SimpleNamespace(
|
||||||
|
session_id="failed",
|
||||||
|
owner_session_key="cli:a",
|
||||||
|
kill=AsyncMock(side_effect=OSError("termination failed")),
|
||||||
|
)
|
||||||
|
manager._sessions[session.session_id] = session
|
||||||
|
|
||||||
|
with pytest.raises(OSError, match="termination failed"):
|
||||||
|
await manager.terminate_by_owner("cli:a")
|
||||||
|
|
||||||
|
assert manager._sessions == {session.session_id: session}
|
||||||
|
session.kill.assert_awaited_once()
|
||||||
|
|
||||||
|
session.kill.side_effect = None
|
||||||
|
assert await manager.terminate_by_owner("cli:a") == 1
|
||||||
|
assert manager._sessions == {}
|
||||||
|
|
||||||
|
asyncio.run(run())
|
||||||
|
|
||||||
|
|
||||||
def test_terminate_by_owner_skips_sessions_without_owner_key(tmp_path):
|
def test_terminate_by_owner_skips_sessions_without_owner_key(tmp_path):
|
||||||
async def run() -> None:
|
async def run() -> None:
|
||||||
manager = ExecSessionManager()
|
manager = ExecSessionManager()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user