pipeline(task): process ErrorFrame in same task and stop pipeline task
This commit is contained in:
@@ -239,7 +239,7 @@ class CancelFrame(SystemFrame):
|
|||||||
class ErrorFrame(SystemFrame):
|
class ErrorFrame(SystemFrame):
|
||||||
"""This is used notify upstream that an error has occurred downstream the
|
"""This is used notify upstream that an error has occurred downstream the
|
||||||
pipeline."""
|
pipeline."""
|
||||||
error: str | None
|
error: str
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.name}(error: {self.error})"
|
return f"{self.name}(error: {self.error})"
|
||||||
@@ -247,9 +247,9 @@ class ErrorFrame(SystemFrame):
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class StopTaskFrame(SystemFrame):
|
class StopTaskFrame(SystemFrame):
|
||||||
"""Indicates that a pipeline task should be stopped. This should inform the
|
"""Indicates that a pipeline task should be stopped but that the pipeline
|
||||||
pipeline processors that they should stop pushing frames but that they
|
processors should be kept in a running state. This is normally queued from
|
||||||
should be kept in a running state.
|
the pipeline task.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -10,7 +10,14 @@ from typing import AsyncIterable, Iterable
|
|||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from pipecat.frames.frames import CancelFrame, EndFrame, ErrorFrame, Frame, MetricsFrame, StartFrame, StopTaskFrame
|
from pipecat.frames.frames import (
|
||||||
|
CancelFrame,
|
||||||
|
EndFrame,
|
||||||
|
ErrorFrame,
|
||||||
|
Frame,
|
||||||
|
MetricsFrame,
|
||||||
|
StartFrame,
|
||||||
|
StopTaskFrame)
|
||||||
from pipecat.pipeline.base_pipeline import BasePipeline
|
from pipecat.pipeline.base_pipeline import BasePipeline
|
||||||
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
|
from pipecat.processors.frame_processor import FrameDirection, FrameProcessor
|
||||||
from pipecat.utils.utils import obj_count, obj_id
|
from pipecat.utils.utils import obj_count, obj_id
|
||||||
@@ -37,10 +44,18 @@ class Source(FrameProcessor):
|
|||||||
|
|
||||||
match direction:
|
match direction:
|
||||||
case FrameDirection.UPSTREAM:
|
case FrameDirection.UPSTREAM:
|
||||||
await self._up_queue.put(frame)
|
await self._handle_upstream_frame(frame)
|
||||||
case FrameDirection.DOWNSTREAM:
|
case FrameDirection.DOWNSTREAM:
|
||||||
await self.push_frame(frame, direction)
|
await self.push_frame(frame, direction)
|
||||||
|
|
||||||
|
async def _handle_upstream_frame(self, frame: Frame):
|
||||||
|
if isinstance(frame, ErrorFrame):
|
||||||
|
logger.error(f"Error running app: {frame.error}")
|
||||||
|
# Cancel all tasks downstream.
|
||||||
|
await self.push_frame(CancelFrame())
|
||||||
|
# Tell the task we should stop.
|
||||||
|
await self._up_queue.put(StopTaskFrame())
|
||||||
|
|
||||||
|
|
||||||
class PipelineTask:
|
class PipelineTask:
|
||||||
|
|
||||||
@@ -70,7 +85,7 @@ class PipelineTask:
|
|||||||
# Make sure everything is cleaned up downstream. This is sent
|
# Make sure everything is cleaned up downstream. This is sent
|
||||||
# out-of-band from the main streaming task which is what we want since
|
# out-of-band from the main streaming task which is what we want since
|
||||||
# we want to cancel right away.
|
# we want to cancel right away.
|
||||||
await self._source.process_frame(CancelFrame(), FrameDirection.DOWNSTREAM)
|
await self._source.push_frame(CancelFrame())
|
||||||
self._process_down_task.cancel()
|
self._process_down_task.cancel()
|
||||||
self._process_up_task.cancel()
|
self._process_up_task.cancel()
|
||||||
await self._process_down_task
|
await self._process_down_task
|
||||||
@@ -134,9 +149,8 @@ class PipelineTask:
|
|||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
frame = await self._up_queue.get()
|
frame = await self._up_queue.get()
|
||||||
if isinstance(frame, ErrorFrame):
|
if isinstance(frame, StopTaskFrame):
|
||||||
logger.error(f"Error running app: {frame.error}")
|
await self.queue_frame(StopTaskFrame())
|
||||||
await self.queue_frame(CancelFrame())
|
|
||||||
self._up_queue.task_done()
|
self._up_queue.task_done()
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user