fix(host): enforce flush=True to prevent pipeline block buffering

This commit is contained in:
mwiegand 2026-05-06 20:30:00 +02:00
parent 27a905c22b
commit 005d2d8458
No known key found for this signature in database
4 changed files with 41 additions and 4 deletions

View file

@ -46,7 +46,7 @@ def run_command(
if on_stderr is not None:
on_stderr(line)
if passthrough:
print(line, file=sys.stderr)
print(line, file=sys.stderr, flush=True)
def terminate_process() -> None:
emit_stderr_message("cancellation requested; terminating subprocess")
@ -82,7 +82,7 @@ def run_command(
if callback is not None:
callback(line)
if passthrough:
print(line, file=output_stream)
print(line, file=output_stream, flush=True)
stream.close()
stdout_thread = threading.Thread(

View file

@ -47,3 +47,21 @@ def test_cancelled_command_raises_cancelled_error() -> None:
def test_run_command_avoids_runtime_unsafe_nested_annotations() -> None:
source = inspect.getsource(run_command)
assert "subprocess.Popen[str].stdout" not in source
def test_run_command_passthrough_writes_to_sys_streams(monkeypatch: pytest.MonkeyPatch) -> None:
import sys
from io import StringIO
mock_stdout = StringIO()
mock_stderr = StringIO()
monkeypatch.setattr(sys, "stdout", mock_stdout)
monkeypatch.setattr(sys, "stderr", mock_stderr)
run_command(
["python3", "-c", "import sys; print('passed out'); print('passed err', file=sys.stderr)"],
passthrough=True,
)
assert mock_stdout.getvalue() == "passed out\n"
assert mock_stderr.getvalue() == "passed err\n"

View file

@ -50,7 +50,7 @@ def run_command(
if on_stderr is not None:
on_stderr(line)
if passthrough:
print(line, file=sys.stderr)
print(line, file=sys.stderr, flush=True)
def terminate_process() -> None:
emit_stderr_message("cancellation requested; terminating subprocess")
@ -86,7 +86,7 @@ def run_command(
if callback is not None:
callback(line)
if passthrough:
print(line, file=output_stream)
print(line, file=output_stream, flush=True)
stream.close()
stdout_thread = threading.Thread(

View file

@ -1,6 +1,25 @@
import sys
from io import StringIO
import pytest
def test_run_command_passthrough_writes_to_sys_streams(monkeypatch: pytest.MonkeyPatch) -> None:
from l4d2web.services.host_commands import run_command
mock_stdout = StringIO()
mock_stderr = StringIO()
monkeypatch.setattr(sys, "stdout", mock_stdout)
monkeypatch.setattr(sys, "stderr", mock_stderr)
run_command(
["python3", "-c", "import sys; print('passed out'); print('passed err', file=sys.stderr)"],
passthrough=True,
)
assert mock_stdout.getvalue() == "passed out\n"
assert mock_stderr.getvalue() == "passed err\n"
def test_run_command_streams_stdout_and_stderr_callbacks() -> None:
from l4d2web.services.host_commands import run_command