fix(runner): use python -u for unbuffered stdout streaming

Python defaults to 4KB block buffering when stdout is a pipe (not a
TTY). Docker attach uses pipes, so print() output accumulated in the
buffer and only flushed when the process exited — the 3-second
sleep(1) loop appeared as a single dump at the end.

python -u (equivalent to PYTHONUNBUFFERED=1) forces line-level
flushing, so each print() is immediately written to the pipe and
picked up by the concurrent log reader → SSE → xterm.js.

Node/Go/Rust already line-buffer to pipes, so only Python needed the
flag. stdout/stderr separation is preserved (no TTY merge).
This commit is contained in:
xfy 2026-07-13 10:03:58 +08:00
parent 2059a55e11
commit aa2d7f3f2d

View File

@ -33,7 +33,11 @@ pub static LANGUAGES: LazyLock<HashMap<String, LanguageDef>> = LazyLock::new(||
"python".to_string(),
LanguageDef {
image: "yggdrasil-runner-python:latest".to_string(),
run_cmd: "python /code/main.py".to_string(),
// -u (unbuffered):强制 stdout/stderr 行刷新。
// 容器 attach 用 pipe非 TTYPython 默认对 pipe 做块缓冲4KB
// 导致流式输出失效——print 的内容攒在缓冲区,进程退出才一次性刷出。
// -u 等价于 PYTHONUNBUFFERED=1让每行 print 立即写出。
run_cmd: "python -u /code/main.py".to_string(),
extension: "py".to_string(),
default_limits: ResourceLimits {
cpu_cores: 1.0,