fix(pipeline): cancel sibling loops on failure (TaskGroup, no close-during-use)
Pipeline.run() used asyncio.gather, so if one loop raised, the failing coroutine propagated while the sibling loops kept running detached; aclose() in the finally then closed a source/stt out from under a still-live loop. Switch to asyncio.TaskGroup so a failing loop cancels+awaits the siblings before teardown. Add a regression test asserting an error in the conversation loop cancels the perception loop and still closes every source.
This commit is contained in:
@@ -102,9 +102,16 @@ class Pipeline:
|
||||
|
||||
# -- lifecycle --------------------------------------------------------- #
|
||||
async def run(self) -> None:
|
||||
loops = [self._perceive(), self._listen_voice(), self._listen_text()]
|
||||
# A TaskGroup (not bare gather) so that if ONE loop raises, the others
|
||||
# are cancelled and awaited before teardown. With plain gather the
|
||||
# failing loop propagated while the siblings kept running detached, and
|
||||
# aclose() in the finally then closed a source/stt out from under a
|
||||
# still-live loop (close-during-use).
|
||||
try:
|
||||
await asyncio.gather(*loops)
|
||||
async with asyncio.TaskGroup() as tg:
|
||||
tg.create_task(self._perceive())
|
||||
tg.create_task(self._listen_voice())
|
||||
tg.create_task(self._listen_text())
|
||||
finally:
|
||||
await self.aclose()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user