fix(pm): bound LiveTail memory for newline-free child output

A child that streams megabytes without a newline grew LiveTail's partial
line (and the retained tail) without limit: 8MB of output kept ~25MB.
Keep only the last MAX_LINE characters of an over-long line; its end is
the informative part.

The streamed-backend-output test now runs in verbose mode: live backend
output is the verbose/CI contract, and quiet mode deliberately contains it.
This commit is contained in:
ethernet
2026-09-24 14:32:29 -04:00
parent 7038ba8f46
commit a89558e312
2 changed files with 6 additions and 2 deletions

View File

@@ -21,6 +21,9 @@ import time
from typing import IO, Callable, Mapping, Optional, Protocol, Sequence
TAIL_LINES = 80
# A child that never prints a newline (a bare progress stream, a binary blob) must not
# grow memory without bound; the end of an over-long line is the informative part.
MAX_LINE = 4096
_TRUE = {"1", "true", "yes", "on"}
_FALSE = {"0", "false", "no", "off"}
_ANSI = re.compile(r"\x1b\[[0-9;?]*[ -/]*[@-~]")
@@ -79,7 +82,7 @@ class LiveTail:
def write(self, text: str) -> int:
# npm and uv redraw with bare CRs; each redraw is a line of progress.
lines = (self._partial + text).replace("\r\n", "\n").replace("\r", "\n").split("\n")
self._partial = lines.pop()
self._partial = lines.pop()[-MAX_LINE:]
for line in lines:
self._line(line)
return len(text)
@@ -106,7 +109,7 @@ class LiveTail:
self._emit("".join(f"{self.indent} {line}\n" for line in self.tail))
def _line(self, line: str) -> None:
line = _ANSI.sub("", line).rstrip()
line = _ANSI.sub("", line[-MAX_LINE:]).rstrip()
if not line.strip():
return
self.tail.append(line)

View File

@@ -301,6 +301,7 @@ def test_build_backend_output_is_streamed_before_build_finishes(installable_proj
import io
from pm.environment import PythonEnvironment
monkeypatch.setenv("HERMES_VERBOSE", "1") # live backend output is the streamed (CI) view's contract
source, uv, env = installable_project
release = tmp_path / "release-build"
stdout_marker = "construction-root: backend stdout"