Skip to content

Commit 74c9e7d

Browse files
committed
fix(core): fire the session-stream onComplete callback at most once
1 parent 9186328 commit 74c9e7d

3 files changed

Lines changed: 14 additions & 5 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
"@trigger.dev/core": patch
33
"@trigger.dev/sdk": patch
4+
"trigger.dev": patch
45
---
56

67
`AgentChat.reconnect()` now settles promptly when reconnecting to an idle chat instead of holding the connection open for the full long-poll window. Also upgrades the S2 streamstore client to 0.25 and moves realtime streams to S2's current hosts.

apps/webapp/test/helpers/sessionStream.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,4 +278,3 @@ export async function collectSessionOut(
278278

279279
return { parts, durationMs: performance.now() - started, subscription };
280280
}
281-

packages/core/src/v3/apiClient/runStream.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ export class SSEStreamSubscription implements StreamSubscription {
204204
private retryNowController: AbortController | null = null;
205205
private internalAbort: AbortController | null = null;
206206
private cancelledByConsumer = false;
207+
private completeNotified = false;
207208

208209
constructor(
209210
private url: string,
@@ -285,6 +286,13 @@ export class SSEStreamSubscription implements StreamSubscription {
285286
this.retryNowController?.abort();
286287
}
287288

289+
/** Fire `onComplete` at most once, even if both the drain and cancel paths reach it. */
290+
private notifyComplete(): void {
291+
if (this.completeNotified) return;
292+
this.completeNotified = true;
293+
this.options.onComplete?.();
294+
}
295+
288296
/**
289297
* The transport pumps decoded records into an internal stream; the returned
290298
* stream drains it on demand.
@@ -316,15 +324,17 @@ export class SSEStreamSubscription implements StreamSubscription {
316324
return;
317325
}
318326
if (result.done) {
319-
self.options.onComplete?.();
320-
controller.close();
327+
self.notifyComplete();
328+
try {
329+
controller.close();
330+
} catch {}
321331
return;
322332
}
323333
controller.enqueue(result.value.part);
324334
},
325335
cancel(reason) {
326336
self.cancelledByConsumer = true;
327-
self.options.onComplete?.();
337+
self.notifyComplete();
328338
internalReader.cancel(reason).catch(() => {});
329339
},
330340
},
@@ -491,7 +501,6 @@ export class SSEStreamSubscription implements StreamSubscription {
491501
},
492502
});
493503
}
494-
495504
}
496505
}
497506
},

0 commit comments

Comments
 (0)