diff --git a/CHANGELOG.md b/CHANGELOG.md index 494fb338a..33a814916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -113,6 +113,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed an issue where the pipeline could freeze if a task cancellation never + completed because a third-party library swallowed asyncio.CancelledError. We + now apply a timeout to task cancellations to prevent these freezes. If the + timeout is reached, the system logs warnings and leaves dangling tasks behind, + which can help diagnose where cancellation is being blocked. + - Fixed an `AudioBufferProcessor` issues that was causing user audio to be missing in stereo recordings causing bot and user overlaps. diff --git a/src/pipecat/processors/frame_processor.py b/src/pipecat/processors/frame_processor.py index 894dabbe7..0b55082aa 100644 --- a/src/pipecat/processors/frame_processor.py +++ b/src/pipecat/processors/frame_processor.py @@ -455,9 +455,13 @@ class FrameProcessor(BaseObject): name = f"{self}::{coroutine.cr_code.co_name}" return self.task_manager.create_task(coroutine, name) - async def cancel_task(self, task: asyncio.Task, timeout: Optional[float] = None): + async def cancel_task(self, task: asyncio.Task, timeout: Optional[float] = 1.0): """Cancel a task managed by this processor. + A default timeout if 1 second is used in order to avoid potential + freezes caused by certain libraries that swallow + `asyncio.CancelledError`. + Args: task: The task to cancel. timeout: Optional timeout for task cancellation.