Commit 34c2d69
authored
fix: stop retrying silent chat streams indefinitely (#4949)
When the server returns `200` without records, chat subscriptions can
retry indefinitely. The client stall timer fires after 60 seconds,
before S2 closes the response at its 120-second timeout, so the existing
EOF budget never applies. Terminal failures also leave persisted
`isStreaming` state active, so a reload starts another subscription.
Normal chat subscriptions now permit five reconnects after stall
timeouts. A separate stall counter preserves unlimited retries for
retryable connection failures, fetch timeouts, and browser wakeups.
Decoded records restore the stall budget. Terminal failures clear state
only for the owning subscription, and watch subscriptions remain
unlimited.
The existing stall timer already ignores keepalives because the parser
drops them before the timer reset. The comment correction does not
change that behavior.
## Checklist
- [x] The PR title follows the contribution convention.
- [x] The changes include tests and a changeset.
- [x] Local package builds, formatting, lint, and knip passed.
- [ ] Maintainer CI and reference-project validation.
## Testing
- Regression tests reproduce timeout exhaustion, indefinite stalls,
stale terminal state, and recovery beyond five connection failures.
- Full suites at `8149b96`: 695 SDK tests and 1,122 core tests passed.
- Final error-message and constructor changes: all 43 stream tests
passed.
- Core and SDK builds passed.
- Repository formatting, lint, and knip passed.
- General and security review passes found no remaining defects.
- The debug-marker check reports existing markers in
`apps/webapp/app/services/previewAutoArchive.server.ts`; the changed
files contain none.
The tests use local HTTP servers. They cover separate stall limits,
fetch timeouts, body failures, keepalives, progress resets, mixed
failures, wakeups, cancellation, watch recovery, and replacement
ownership. Core tests exercise stall exhaustion with short timers. The
SDK's six-minute silence window needs reference-project validation.
## Changelog
Silent chat subscriptions now report `Stream stalled: no records
received` after five stall retries. Network failures retain automatic
recovery, and watch subscriptions remain unlimited.
## Risk
| Condition | Result |
| --- | --- |
| Retryable connection or fetch failure | No finite retry deadline;
exponential backoff continues |
| Repeated connected silence | The sixth 60-second stall ends the
subscription |
| Browser wake or `online` event | Reconnect without consuming or
restoring the stall budget |
With immediate response headers, six silent attempts take 368.5–377
seconds, about 6.1–6.3 minutes. Network delays extend this window. A
healthy tool call with no records can also reach this limit: silence
does not prove that the run is dead. The terminal error stops automatic
client resumption but does not cancel the server-side run.
Shared core consumers retain their configured retry limits. Repeated
successful responses without records now increase backoff until a
decoded record arrives. Caller cancellation and token-refresh limits
remain unchanged.1 parent 8067b1f commit 34c2d69
5 files changed
Lines changed: 380 additions & 16 deletions
File tree
- .changeset
- packages
- core/src/v3/apiClient
- trigger-sdk/src/v3
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
Lines changed: 188 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
219 | 219 | | |
220 | 220 | | |
221 | 221 | | |
| 222 | + | |
222 | 223 | | |
| 224 | + | |
223 | 225 | | |
224 | 226 | | |
225 | 227 | | |
| |||
273 | 275 | | |
274 | 276 | | |
275 | 277 | | |
276 | | - | |
277 | | - | |
| 278 | + | |
278 | 279 | | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
279 | 283 | | |
280 | 284 | | |
281 | 285 | | |
| |||
293 | 297 | | |
294 | 298 | | |
295 | 299 | | |
| 300 | + | |
296 | 301 | | |
297 | 302 | | |
298 | 303 | | |
| |||
403 | 408 | | |
404 | 409 | | |
405 | 410 | | |
406 | | - | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
407 | 416 | | |
408 | 417 | | |
409 | 418 | | |
| |||
461 | 470 | | |
462 | 471 | | |
463 | 472 | | |
464 | | - | |
465 | 473 | | |
466 | 474 | | |
467 | 475 | | |
| |||
576 | 584 | | |
577 | 585 | | |
578 | 586 | | |
579 | | - | |
| 587 | + | |
580 | 588 | | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
581 | 592 | | |
582 | 593 | | |
583 | 594 | | |
| |||
644 | 655 | | |
645 | 656 | | |
646 | 657 | | |
647 | | - | |
648 | | - | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
649 | 666 | | |
650 | 667 | | |
651 | 668 | | |
| |||
0 commit comments