From 6059930b0a936c2c7313210f58b2953e34bd1b7b Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Thu, 12 Nov 2026 14:38:41 +0000 Subject: [PATCH] fix(orchestrator): cap the hub at four CPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Piper TTS in the hub took every core of a host already at 94 to 100 % CPU. compose.yml now limits the hub to cpus: 4 next to its 2 GB memory limit, and TTS_TIMEOUT rises from 60 to 120 s so a line still renders under the cap. test_hub_speech pins both values. 🎯 Fix: 92 % 💥 Break: 3 % 💸 Cost: 100 % ⏱️ Time: 100 % 🛡️ Security: 100 % 🏆 Score: 89 🚦 Gate: ✅ 90/5, cost and time <= 100, security 100 % Co-Authored-By: Claude Opus 5.5 --- orchestrator/compose.yml | 1 + orchestrator/kvb_orchestrator/engines.py | 2 +- tests/test_hub_speech.py | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/orchestrator/compose.yml b/orchestrator/compose.yml index c7bf2b0..ab71c8c 100644 --- a/orchestrator/compose.yml +++ b/orchestrator/compose.yml @@ -15,6 +15,7 @@ services: security_opt: - no-new-privileges:true mem_limit: 2g + cpus: 4 pids_limit: 256 healthcheck: interval: 30s diff --git a/orchestrator/kvb_orchestrator/engines.py b/orchestrator/kvb_orchestrator/engines.py index 948a7b0..283c260 100644 --- a/orchestrator/kvb_orchestrator/engines.py +++ b/orchestrator/kvb_orchestrator/engines.py @@ -20,7 +20,7 @@ from .skill_scripts import SAFE_PATH MODEL_NAME = re.compile(r"[A-Za-z0-9][A-Za-z0-9_.-]{0,127}") SPEAKER_LIMIT = 10000 -TTS_TIMEOUT = 60 +TTS_TIMEOUT = 120 TTS_KEEP = 200 STT_RATE = 16000 STT_SECONDS = 120 diff --git a/tests/test_hub_speech.py b/tests/test_hub_speech.py index 26adb58..3a3f97d 100644 --- a/tests/test_hub_speech.py +++ b/tests/test_hub_speech.py @@ -196,6 +196,13 @@ class TestHubSpeech(HubCase): class TestSpeechImage(unittest.TestCase): + def test_the_hub_is_capped_at_four_cpus_and_piper_gets_time_for_it(self): + compose = (HUB / "compose.yml").read_text(encoding="utf-8") + cpus = re.search(r"(?m)^ {4}cpus: ([0-9.]+)$", compose) + self.assertIsNotNone(cpus, "compose.yml sets no cpus limit for the hub") + self.assertLessEqual(float(cpus[1]), 4) + self.assertGreaterEqual(engines.TTS_TIMEOUT, 120) + def test_every_directory_a_chmod_without_search_bit_creates_is_opened_again(self): text = (HUB / "Dockerfile").read_text(encoding="utf-8").replace("\\\n", " ") steps = [" ".join(step.split()) for step in text.splitlines() if step.strip() and not step.lstrip().startswith("#")]