Spaces:
Sleeping
Sleeping
Upload server/pipeline_engine.py with huggingface_hub
Browse files- server/pipeline_engine.py +27 -19
server/pipeline_engine.py
CHANGED
|
@@ -54,7 +54,9 @@ class ServiceState:
|
|
| 54 |
self.target_version = version
|
| 55 |
|
| 56 |
# 8% chance of transient staging failure on first attempt
|
| 57 |
-
|
|
|
|
|
|
|
| 58 |
self.staging_deployed = True # deployed but not verified
|
| 59 |
self.logs.append(
|
| 60 |
f"[DEPLOY] Deployed {self.name} {version} to staging. "
|
|
@@ -147,8 +149,13 @@ class ServiceState:
|
|
| 147 |
self.latency_ms = round(base_latency * (1.0 + 0.3 * recovery_steps), 1)
|
| 148 |
self.error_rate = round(base_error_rate * (1.0 + 0.5 * recovery_steps), 3)
|
| 149 |
# Trade-off: deploy causes temporary CPU/latency spike (warmup load)
|
| 150 |
-
|
| 151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
self.last_deploy_timestamp = "2026-04-01T12:00:00Z"
|
| 153 |
self.logs.append(
|
| 154 |
f"[DEPLOY] Promoted {self.name} {version} to production. Health: HEALTHY. "
|
|
@@ -272,9 +279,10 @@ class PipelineEngine:
|
|
| 272 |
# Initialize from scenario
|
| 273 |
scenario.setup(self)
|
| 274 |
|
| 275 |
-
# Inject the shared RNG into all services created by the scenario
|
| 276 |
for svc in self.services.values():
|
| 277 |
svc._rng = self._rng
|
|
|
|
| 278 |
|
| 279 |
def execute(self, action):
|
| 280 |
"""Execute an action. Returns human-readable result string."""
|
|
@@ -320,13 +328,13 @@ class PipelineEngine:
|
|
| 320 |
def _tick_metric_compounding(self):
|
| 321 |
"""Metrics compound on each other β creates realistic spirals and recovery."""
|
| 322 |
for name, svc in self.services.items():
|
| 323 |
-
# Degradation spirals
|
| 324 |
-
if svc.error_rate >
|
| 325 |
-
svc.cpu_percent = min(svc.cpu_percent +
|
| 326 |
-
if svc.cpu_percent >
|
| 327 |
-
svc.latency_ms = round(min(svc.latency_ms +
|
| 328 |
-
if svc.latency_ms >
|
| 329 |
-
svc.error_rate = round(min(svc.error_rate +
|
| 330 |
|
| 331 |
# Natural recovery (when metrics are good, they help each other)
|
| 332 |
if svc.error_rate < 2.0:
|
|
@@ -359,13 +367,13 @@ class PipelineEngine:
|
|
| 359 |
|
| 360 |
# Determine cascade severity
|
| 361 |
if health_pct < 20.0:
|
| 362 |
-
# Source is effectively down β
|
| 363 |
-
err_increase =
|
| 364 |
-
lat_increase =
|
| 365 |
else:
|
| 366 |
# Source is degraded β lighter cascade
|
| 367 |
-
err_increase =
|
| 368 |
-
lat_increase =
|
| 369 |
|
| 370 |
old_err = dep.error_rate
|
| 371 |
dep.error_rate = round(min(dep.error_rate + err_increase, 45.0), 2)
|
|
@@ -637,11 +645,11 @@ class PipelineEngine:
|
|
| 637 |
if task == "judgment_call":
|
| 638 |
api_gw = self.services.get("api-gateway")
|
| 639 |
if api_gw and api_gw.health == ServiceHealth.DEGRADED:
|
| 640 |
-
degrade_lat =
|
| 641 |
-
degrade_err =
|
| 642 |
api_gw.latency_ms = round(min(api_gw.latency_ms + degrade_lat, 5000), 1)
|
| 643 |
api_gw.error_rate = round(min(api_gw.error_rate + degrade_err, 50.0), 2)
|
| 644 |
-
api_gw.cpu_percent = min(api_gw.cpu_percent +
|
| 645 |
api_gw.logs.append(
|
| 646 |
f"[DEGRADING] api-gateway latency now {api_gw.latency_ms:.0f}ms, "
|
| 647 |
f"errors {api_gw.error_rate:.1f}/s β situation worsening"
|
|
|
|
| 54 |
self.target_version = version
|
| 55 |
|
| 56 |
# 8% chance of transient staging failure on first attempt
|
| 57 |
+
# Skip transient failure during incidents (health already degraded/down)
|
| 58 |
+
transient_roll = self._rng.random()
|
| 59 |
+
if not self.staging_verified and self.health == ServiceHealth.HEALTHY and transient_roll < 0.08:
|
| 60 |
self.staging_deployed = True # deployed but not verified
|
| 61 |
self.logs.append(
|
| 62 |
f"[DEPLOY] Deployed {self.name} {version} to staging. "
|
|
|
|
| 149 |
self.latency_ms = round(base_latency * (1.0 + 0.3 * recovery_steps), 1)
|
| 150 |
self.error_rate = round(base_error_rate * (1.0 + 0.5 * recovery_steps), 3)
|
| 151 |
# Trade-off: deploy causes temporary CPU/latency spike (warmup load)
|
| 152 |
+
# Clean deploy tasks get reduced spikes β they should be clean
|
| 153 |
+
if hasattr(self, '_task_name') and self._task_name == "clean_deploy":
|
| 154 |
+
self.cpu_percent = min(self.cpu_percent + 5, 99)
|
| 155 |
+
self.latency_ms += round(50 * self._rng.uniform(0.8, 1.2), 1)
|
| 156 |
+
else:
|
| 157 |
+
self.cpu_percent = min(self.cpu_percent + 15, 99)
|
| 158 |
+
self.latency_ms += round(200 * self._rng.uniform(0.8, 1.2), 1)
|
| 159 |
self.last_deploy_timestamp = "2026-04-01T12:00:00Z"
|
| 160 |
self.logs.append(
|
| 161 |
f"[DEPLOY] Promoted {self.name} {version} to production. Health: HEALTHY. "
|
|
|
|
| 279 |
# Initialize from scenario
|
| 280 |
scenario.setup(self)
|
| 281 |
|
| 282 |
+
# Inject the shared RNG and task name into all services created by the scenario
|
| 283 |
for svc in self.services.values():
|
| 284 |
svc._rng = self._rng
|
| 285 |
+
svc._task_name = scenario.task_name
|
| 286 |
|
| 287 |
def execute(self, action):
|
| 288 |
"""Execute an action. Returns human-readable result string."""
|
|
|
|
| 328 |
def _tick_metric_compounding(self):
|
| 329 |
"""Metrics compound on each other β creates realistic spirals and recovery."""
|
| 330 |
for name, svc in self.services.items():
|
| 331 |
+
# Degradation spirals (moderate β should not kill episodes in <5 steps)
|
| 332 |
+
if svc.error_rate > 15.0:
|
| 333 |
+
svc.cpu_percent = min(svc.cpu_percent + 3, 99)
|
| 334 |
+
if svc.cpu_percent > 90:
|
| 335 |
+
svc.latency_ms = round(min(svc.latency_ms + 100, 5000), 1)
|
| 336 |
+
if svc.latency_ms > 3000:
|
| 337 |
+
svc.error_rate = round(min(svc.error_rate + 1.0, 50.0), 2)
|
| 338 |
|
| 339 |
# Natural recovery (when metrics are good, they help each other)
|
| 340 |
if svc.error_rate < 2.0:
|
|
|
|
| 367 |
|
| 368 |
# Determine cascade severity
|
| 369 |
if health_pct < 20.0:
|
| 370 |
+
# Source is effectively down β moderate cascade
|
| 371 |
+
err_increase = 1.5
|
| 372 |
+
lat_increase = 30.0
|
| 373 |
else:
|
| 374 |
# Source is degraded β lighter cascade
|
| 375 |
+
err_increase = 0.5
|
| 376 |
+
lat_increase = 10.0
|
| 377 |
|
| 378 |
old_err = dep.error_rate
|
| 379 |
dep.error_rate = round(min(dep.error_rate + err_increase, 45.0), 2)
|
|
|
|
| 645 |
if task == "judgment_call":
|
| 646 |
api_gw = self.services.get("api-gateway")
|
| 647 |
if api_gw and api_gw.health == ServiceHealth.DEGRADED:
|
| 648 |
+
degrade_lat = 80 * self._rng.uniform(0.8, 1.2)
|
| 649 |
+
degrade_err = 0.8 * self._rng.uniform(0.9, 1.1)
|
| 650 |
api_gw.latency_ms = round(min(api_gw.latency_ms + degrade_lat, 5000), 1)
|
| 651 |
api_gw.error_rate = round(min(api_gw.error_rate + degrade_err, 50.0), 2)
|
| 652 |
+
api_gw.cpu_percent = min(api_gw.cpu_percent + 1, 99)
|
| 653 |
api_gw.logs.append(
|
| 654 |
f"[DEGRADING] api-gateway latency now {api_gw.latency_ms:.0f}ms, "
|
| 655 |
f"errors {api_gw.error_rate:.1f}/s β situation worsening"
|