Handle incoming request cancellation in Workers with Request.signal
In Cloudflare Workers, you can now attach an event listener to Request objects, using the signal property ↗. This allows you to perform tasks when the request to your Worker is canceled by the client. To use this feature, you must set the enable_request_signal compatibility flag.
You can use a listener to perform cleanup tasks or write to logs before your Worker's invocation ends. For example, if you run the Worker below, and then abort the request from the client, a log will be written:
export default {
async fetch(request, env, ctx) {
// This sets up an event listener that will be called if the client disconnects from your
// worker.
request.signal.addEventListener("abort", () => {
console.log("The request was aborted!");
});
const { readable, writable } = new IdentityTransformStream();
sendPing(writable);
return new Response(readable, {
headers: { "Content-Type": "text/plain" },
});
},
};
async function sendPing(writable) {
const writer = writable.getWriter();
const enc = new TextEncoder();
for (;;) {
// Send 'ping' every second to keep the connection alive
await writer.write(enc.encode("ping\r\n"));
await scheduler.wait(1000);
}
}export default {
async fetch(request, env, ctx): Promise<Response> {
// This sets up an event listener that will be called if the client disconnects from your
// worker.
request.signal.addEventListener('abort', () => {
console.log('The request was aborted!');
});
const { readable, writable } = new IdentityTransformStream();
sendPing(writable);
return new Response(readable, { headers: { 'Content-Type': 'text/plain' } });
},
} satisfies ExportedHandler<Env>;
async function sendPing(writable: WritableStream): Promise<void> {
const writer = writable.getWriter();
const enc = new TextEncoder();
for (;;) {
// Send 'ping' every second to keep the connection alive
await writer.write(enc.encode('ping\r\n'));
await scheduler.wait(1000);
}
}For more information see the Request documentation.