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:
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user