mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
## Description The compression-pipeline timeout was hard-coded at 30s, so slow CPUs and long Claude Code conversations had no recourse. #946 asks to wire `HEADROOM_COMPRESSION_TIMEOUT_SECONDS` through. Refs #946. ## Type of Change - [x] New feature (non-breaking change that adds functionality) ## Changes Made - Read `HEADROOM_COMPRESSION_TIMEOUT_SECONDS` from the environment (float), falling back to 30 on an unparseable value. ## Testing - [x] Unit tests pass (`pytest`) - [x] New tests added for new functionality ### Test Output ```text $ pytest tests/test_proxy/test_compression_timeout_config.py -q 4 passed in 0.09s ``` ## Real Behavior Proof - Environment: Linux, Python 3.13, editable build of this branch - Exact command / steps: `HEADROOM_COMPRESSION_TIMEOUT_SECONDS=88 python -c "import headroom.proxy.helpers as h; print(h.COMPRESSION_TIMEOUT_SECONDS)"` - Observed result: prints `88.0` (default `30.0`; an unparseable value falls back to `30.0`) - Not tested: a live compression actually exceeding the configured timeout under real load ## Review Readiness - [x] I have performed a self-review - [x] This PR is ready for human review --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
5208e32d64
commit
addebdb29c
2 changed files with 50 additions and 2 deletions
|
|
@ -770,8 +770,15 @@ def parse_sse_events_from_byte_buffer(
|
|||
# Maximum message array length (prevents DoS from deeply nested payloads)
|
||||
MAX_MESSAGE_ARRAY_LENGTH = 10000
|
||||
|
||||
# Compression pipeline timeout in seconds
|
||||
COMPRESSION_TIMEOUT_SECONDS = 30
|
||||
# Compression pipeline timeout in seconds. Override via the
|
||||
# HEADROOM_COMPRESSION_TIMEOUT_SECONDS env var for slow CPUs or long Claude Code
|
||||
# conversations (GH #946). Falls back to 30 on an unparseable value.
|
||||
try:
|
||||
COMPRESSION_TIMEOUT_SECONDS = float(
|
||||
os.environ.get("HEADROOM_COMPRESSION_TIMEOUT_SECONDS", "30")
|
||||
)
|
||||
except ValueError:
|
||||
COMPRESSION_TIMEOUT_SECONDS = 30.0
|
||||
|
||||
# Maximum compression cache sessions (prevents unbounded memory growth)
|
||||
MAX_COMPRESSION_CACHE_SESSIONS = 500
|
||||
|
|
|
|||
41
tests/test_proxy/test_compression_timeout_config.py
Normal file
41
tests/test_proxy/test_compression_timeout_config.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
import headroom.proxy.helpers as helpers
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _restore_default_timeout():
|
||||
"""Each test reloads helpers under a chosen env; reset to the default afterwards
|
||||
so the reloaded module constant doesn't leak into the rest of the suite."""
|
||||
yield
|
||||
os.environ.pop("HEADROOM_COMPRESSION_TIMEOUT_SECONDS", None)
|
||||
importlib.reload(helpers)
|
||||
|
||||
|
||||
def test_default_timeout_is_30(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.delenv("HEADROOM_COMPRESSION_TIMEOUT_SECONDS", raising=False)
|
||||
importlib.reload(helpers)
|
||||
assert helpers.COMPRESSION_TIMEOUT_SECONDS == 30.0
|
||||
|
||||
|
||||
def test_env_overrides_timeout(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("HEADROOM_COMPRESSION_TIMEOUT_SECONDS", "75")
|
||||
importlib.reload(helpers)
|
||||
assert helpers.COMPRESSION_TIMEOUT_SECONDS == 75.0
|
||||
|
||||
|
||||
def test_fractional_timeout(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("HEADROOM_COMPRESSION_TIMEOUT_SECONDS", "12.5")
|
||||
importlib.reload(helpers)
|
||||
assert helpers.COMPRESSION_TIMEOUT_SECONDS == 12.5
|
||||
|
||||
|
||||
def test_bad_env_falls_back_to_default(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("HEADROOM_COMPRESSION_TIMEOUT_SECONDS", "not-a-number")
|
||||
importlib.reload(helpers)
|
||||
assert helpers.COMPRESSION_TIMEOUT_SECONDS == 30.0
|
||||
Loading…
Add table
Add a link
Reference in a new issue