Commit 65c8dbe
feat(fetch): honor AbortSignal — cancel/timeout in-flight requests (#5690)
`fetch(url, { signal })` ignored the signal: `js_fetch_with_options` took only
url/method/body/headers and ran to completion, so neither `controller.abort()`
nor `AbortSignal.timeout(ms)` could cancel it. And `AbortSignal.timeout(ms)` was
a no-op stub returning a never-aborting signal. Together,
`fetch(url, { signal: AbortSignal.timeout(ms) })` on a slow/held response hung
forever instead of rejecting at the deadline.
This wires AbortSignal through the fetch path:
- `AbortSignal.timeout(ms)` (`url/abort.rs`) now schedules a real (unref'd)
callback timer that aborts the signal with a `TimeoutError` and fires its
`abort` listeners when the deadline elapses on the main thread.
- The signal reaches the stdlib fetch via a thread-local stash
(`js_fetch_set_pending_signal`), keeping the 4-arg ABI unchanged. The runtime
fetch thunk sets it for the dynamic/aliased path; codegen emits it before the
call for the `fetch(url, { … })` fast path (a new `signal` field on the
`FetchWithOptions` HIR node).
- `js_fetch_with_options` registers a per-request `tokio::sync::Notify` keyed to
the signal and `select!`s the request against it; on abort it drops the
request future (cancelling the in-flight reqwest request) and rejects with an
`AbortError`. An already-aborted signal rejects up front. The abort reaches
the request through the runtime: `fire_abort_listeners` calls
`js_fetch_notify_signal_aborted` on every abort — so there is no per-fetch JS
listener to accumulate on reused signals.
The pending signal is consumed before the promise is allocated (so a GC during
allocation can't move the TLS-stashed signal). No behavior change for
signal-less fetches; the WASM fetch backend keeps its existing behavior.
Co-authored-by: Ralph Küpper <ralph2@skelpo.com>1 parent 5ed83fb commit 65c8dbe
20 files changed
Lines changed: 455 additions & 79 deletions
File tree
- crates
- perry-codegen-js/src/emit
- perry-codegen-wasm/src/emit
- expr
- perry-codegen/src
- collectors
- expr
- runtime_decls/stdlib_ffi
- perry-hir/src
- ir
- lower/expr_call
- stable_hash
- walker
- perry-runtime/src
- object
- url
- perry-stdlib/src/fetch
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| 42 | + | |
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
| |||
63 | 64 | | |
64 | 65 | | |
65 | 66 | | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
66 | 71 | | |
67 | 72 | | |
68 | 73 | | |
| |||
Lines changed: 3 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
32 | 35 | | |
33 | 36 | | |
34 | 37 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
354 | 354 | | |
355 | 355 | | |
356 | 356 | | |
| 357 | + | |
357 | 358 | | |
358 | 359 | | |
359 | 360 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
972 | 972 | | |
973 | 973 | | |
974 | 974 | | |
| 975 | + | |
975 | 976 | | |
976 | 977 | | |
977 | 978 | | |
| |||
983 | 984 | | |
984 | 985 | | |
985 | 986 | | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
986 | 990 | | |
987 | 991 | | |
988 | 992 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
669 | 669 | | |
670 | 670 | | |
671 | 671 | | |
| 672 | + | |
672 | 673 | | |
673 | 674 | | |
674 | 675 | | |
| |||
679 | 680 | | |
680 | 681 | | |
681 | 682 | | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
682 | 686 | | |
683 | 687 | | |
684 | 688 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
754 | 754 | | |
755 | 755 | | |
756 | 756 | | |
| 757 | + | |
757 | 758 | | |
758 | 759 | | |
759 | 760 | | |
| |||
764 | 765 | | |
765 | 766 | | |
766 | 767 | | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
767 | 771 | | |
768 | 772 | | |
769 | 773 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
| 83 | + | |
83 | 84 | | |
84 | 85 | | |
85 | 86 | | |
86 | 87 | | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
87 | 94 | | |
88 | 95 | | |
89 | 96 | | |
| |||
141 | 148 | | |
142 | 149 | | |
143 | 150 | | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
144 | 156 | | |
145 | 157 | | |
146 | 158 | | |
| |||
Lines changed: 3 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
147 | 147 | | |
148 | 148 | | |
149 | 149 | | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
150 | 153 | | |
151 | 154 | | |
152 | 155 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
515 | 515 | | |
516 | 516 | | |
517 | 517 | | |
| 518 | + | |
518 | 519 | | |
519 | 520 | | |
520 | 521 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
489 | 489 | | |
490 | 490 | | |
491 | 491 | | |
| 492 | + | |
492 | 493 | | |
493 | 494 | | |
494 | 495 | | |
| |||
506 | 507 | | |
507 | 508 | | |
508 | 509 | | |
| 510 | + | |
509 | 511 | | |
510 | 512 | | |
511 | 513 | | |
| |||
520 | 522 | | |
521 | 523 | | |
522 | 524 | | |
| 525 | + | |
523 | 526 | | |
524 | 527 | | |
525 | 528 | | |
| |||
539 | 542 | | |
540 | 543 | | |
541 | 544 | | |
| 545 | + | |
542 | 546 | | |
543 | 547 | | |
544 | 548 | | |
| |||
0 commit comments