From dc3d6c8b7bd13ed569d7eb89817fd5d07bee3893 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Sun, 24 Mar 2024 09:44:03 +0100 Subject: [PATCH] Prevent stderr pipe buffer overflow on long running radio streams (#1170) * Fix buffer overflow in stderr reading * Prevent pipe buffer overflooding --- music_assistant/server/helpers/process.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/music_assistant/server/helpers/process.py b/music_assistant/server/helpers/process.py index 1dfc043d..61e528a7 100644 --- a/music_assistant/server/helpers/process.py +++ b/music_assistant/server/helpers/process.py @@ -100,6 +100,10 @@ class AsyncProcess: stdin=stdin if self._enable_stdin else None, stdout=stdout if self._enable_stdout else None, stderr=asyncio.subprocess.PIPE if self._enable_stderr else None, + # setting the buffer limit is important to prevent exceeding the limit + # when reading lines from stderr (e.g. with long running ffmpeg process) + # https://stackoverflow.com/questions/55457370/how-to-avoid-valueerror-separator-is-not-found-and-chunk-exceed-the-limit + limit=1024 * 1024, ) LOGGER.debug("Started %s with PID %s", self._name, self.proc.pid) @@ -216,9 +220,17 @@ class AsyncProcess: async def iter_stderr(self) -> AsyncGenerator[bytes, None]: """Iterate lines from the stderr stream.""" - async with self._stderr_locked: - async for line in self.proc.stderr: - yield line + while not self.closed: + try: + async with self._stderr_locked: + async for line in self.proc.stderr: + yield line + except ValueError as err: + # we're waiting for a line (separator found), but the line was too big + # NOTE: this consumes the line that was too big + if "chunk exceed the limit" in str(err): + continue + raise async def _feed_stdin(self, custom_stdin: AsyncGenerator[bytes, None]) -> None: """Feed stdin with chunks from an AsyncGenerator.""" -- 2.34.1