File
Blob: src/workerd/api/tests/request-signal-passthrough.js
| 1 | // Copyright (c) 2025 Cloudflare, Inc. |
| 2 | // Licensed under the Apache 2.0 license found in the LICENSE file or at: |
| 3 | // https://opensource.org/licenses/Apache-2.0 |
| 4 | import { WorkerEntrypoint } from 'cloudflare:workers'; |
| 5 | import assert from 'node:assert'; |
| 6 | |
| 7 | let reqSignalReason = null; |
| 8 | let rpcSignalReason = null; |
| 9 | |
| 10 | export class OtherServer extends WorkerEntrypoint { |
| 11 | async echo(val) { |
| 12 | return val; |
| 13 | } |
| 14 | |
| 15 | async saveReqReason(req) { |
| 16 | rpcSignalReason = req.signal.reason?.message; |
| 17 | } |
| 18 | } |
| 19 | |
| 20 | export class Server extends WorkerEntrypoint { |
| 21 | async fetch(req) { |
| 22 | // req.signal is in the "this signal" slot. Because request_signal_passthrough is set, there is |
| 23 | // no special handling. |
| 24 | req.signal.onabort = () => { |
| 25 | // If we're here we know that the reason is filled in on req.signal |
| 26 | reqSignalReason = req.signal.reason.message; |
| 27 | |
| 28 | // Ensure that the incoming request signal is in the "signal" slot, which is the one we |
| 29 | // actually serialize currently. |
| 30 | const newReq = req.clone(); |
| 31 | |
| 32 | // And if the signal really is included in serialization, OtherServer will be able to read |
| 33 | // the reason. |
| 34 | this.ctx.waitUntil(this.env.OtherServer.saveReqReason(newReq)); |
| 35 | }; |
| 36 | |
| 37 | // Just hang and wait for the client to give up |
| 38 | await scheduler.wait(86400); |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | export const requestPassedOverRpcIncludesSignal = { |
| 43 | async test(ctrl, env, ctx) { |
| 44 | await assert.rejects( |
| 45 | () => |
| 46 | env.Server.fetch('http://example.com', { |
| 47 | signal: AbortSignal.timeout(100), |
| 48 | }), |
| 49 | { message: 'The operation was aborted due to timeout' } |
| 50 | ); |
| 51 | |
| 52 | // Yield so the workers can write the abort reasons |
| 53 | await scheduler.wait(0); |
| 54 | |
| 55 | assert.strictEqual(reqSignalReason, 'The client has disconnected'); |
| 56 | assert.strictEqual(rpcSignalReason, 'The client has disconnected'); |
| 57 | }, |
| 58 | }; |