• v2.2.6-ew-limits-1 b3c945c053

    v2.2.6-ew-limits-1
    All checks were successful
    Docker Build / docker (push) Successful in 9m19s
    Docker Release / release (push) Successful in 7m43s
    Stable

    engel75 released this 2026-10-13 09:01:45 +02:00 | -3620 commits to 1.4.23-ew since this release

    Bifrost v2.2.6-ew-limits-1 (EW Fork)

    Feature-Release: Per-Entry Capacity Lanes (Spec 12) — Umbau des Limits-Systems im EW-Provider.

    EW-Feature: Entry Lanes (Spec 12)

    • ew_key_config.capacity pro EW-Key/Entry: {concurrency, queue_size, queue_timeout_seconds, drop_excess} — eigene Drossel pro SGLang-Backend/Gateway-VIP vor dem Backend-Call
    • Semaphore + begrenzte FIFO-Warteschlange mit Warte-Timeout; Überlast → deterministisches 429 statt unbegrenztem Queue-Stau (Klasse des 540s-Overhead-Vorfalls strukturell beendet)
    • Rotation: Lane-429 ist rotation-fähig (IsBifrostError=false) — Spill-Over auf den nächsten Entry mit network_config.max_retries ≥ 1; client-seitig erscheint der Fehler als rate_limit_error mit Message-Signatur "is at its concurrency limit"
    • Registry überlebt Provider-Recreation (Key-CRUD); nil/abwesende capacity = unbegrenzt (exakt Altverhalten, kein Backfill nötig)
    • Streams halten den Slot bis Stream-Ende (Concurrency-Einheit, spiegelbildlich zum SGLang-Model-Gateway)

    Konfiguration & Verwaltung

    • UI: Capacity-Felder im EW-Key-Formular (concurrency / queue_size / queue_timeout_seconds / drop_excess) + Tabellen-Anzeige; Zod-Validierung spiegelt die Server-Regeln
    • config.schema.json: EW-Provider erstmals first-class (providers-Map-Entry + $defs.ew_key + provider_with_ew_config)
    • Observability: ew.lane-wait-Span → overhead_breakdown-Bucket in den Request-Logs + Prometheus-Histogramm bifrost_ew_lane_wait_seconds {provider, key_id, key_name, outcome}
    • Persistenz: 1 additive Spalte keys.ew_capacity_json (Migration EW-LAST, NULL = Altverhalten)

    Begleitfixes

    • keyDialTargets: ew_key_config.url jetzt im SSRF/Endpoint-Change-Guard — Verhaltenswechsel für Deployments mit deaktivierter Dashboard-Auth: Ändern einer EW-Key-URL ohne Auth → 403 (authentifiziert unverändert)
    • Timeout-Klassifikation korrigiert: Client-Deadline während des Wartens → 504 request_timed_out statt rotation-fähigem 429 (tote Requests rotieren nicht)

    Operator-Hinweise

    • Spill-Over aktivieren: network_config.max_retries ≥ 1 setzen — sonst ist ein Lane-429 final
    • Sizing: Entry-Capacity ≈ Gateway --max-concurrent-requests × Replikas bzw. Σ Instanz-Kapazität; N Bifrost-Prozesse = N× konfigurierte Concurrency pro Entry (keine Cross-Node-Koordination)
    • Bekannte Lücke: TranscriptionStream-Passthrough-Modus unterzählt die Lane während des Passthrough-Streamings (dokumentiert, kein Leak)
    • Retry-After-Header wird bei Lane-429s nicht gesetzt

    Qualität

    • 13 Commits auf Branch ew-limits-rework (Plan ew-per-entry-queue-limits; Final Wave 4× APPROVE: Compliance / Code-Quality / Manual-QA / Scope)
    • Lost-Wakeup-Race im Lane-Release vom Review gefunden und gefixt (Restock unter Lock, Regressionstest); Cancel-vs-Timeout-Race ebenfalls gefixt
    • Stress-Test 200 Goroutines (max in-flight ≤ cap, rejected = total − admitted), go test -race -count=20 grün, nil-Capacity-Pfad 0 allocs/op
    • Alle Module frisch gebaut/gevettet/getestet (core, framework, transports, telemetry, UI build + vitest 9/9); Harness-Case 8.5.U strukturell validiert (augment 639 Requests / 324 Guards, FEATURE=lane → 1 Request)

    Details: specs/12-ew-entry-lanes.md
    Image: forge.engelmann.me/engel75/bifrost:v2.2.6-ew-limits-1

    Downloads