llmrouter: Slot an das Verbindungssignal binden (cancel feuert nicht)
Gegenprobe am Produktivrouter nach dem ersten Fix: Ein abgebrochener Stream gab den Slot WEITERHIN nicht frei -- cancel() im TransformStream wird von Bun beim Verbindungsabbruch nicht aufgerufen. Immerhin griff die zweite Haerte: statt zwei Stunden Stille gab es nach 30 s ein 503 mit Grund. Jetzt haengt der Slot an req.signal, das beim Abbruch zuverlaessig feuert, plus einem Sicherheitsnetz von 660 s (laenger als der Upstream-Timeout darf kein Slot gehalten werden). Die Freigabe ist gegen Doppelaufruf gesichert, ein spaeteres flush() schadet also nicht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -348,6 +348,16 @@ Bun.serve({
|
||||
let freigeben: () => void;
|
||||
try {
|
||||
freigeben = await belegen(ziel.upstreamName, ziel.upstream);
|
||||
// Der Slot haengt am LEBEN DER VERBINDUNG, nicht am Ende des Streams.
|
||||
// Gegenprobe am 2026-09-07: cancel() im TransformStream feuert in Bun
|
||||
// NICHT, wenn der Client abbricht -- der Slot blieb belegt, und erst die
|
||||
// 30-s-Frist machte daraus ein 503 statt Stille (42i/intern#1283).
|
||||
// req.signal feuert dagegen zuverlaessig; die Freigabe ist gegen
|
||||
// Doppelaufruf gesichert, ein spaeteres flush() schadet also nicht.
|
||||
// Dazu ein Sicherheitsnetz: laenger als der Upstream-Timeout darf kein
|
||||
// Slot gehalten werden, egal was passiert.
|
||||
req.signal.addEventListener("abort", () => freigeben(), { once: true });
|
||||
setTimeout(() => freigeben(), 660_000);
|
||||
} catch (e) {
|
||||
if (e instanceof SlotFrist) {
|
||||
eintrag.status = 503; eintrag.fehler = e.message; abschliessen();
|
||||
|
||||
Reference in New Issue
Block a user