shiichan

AbortController Now Works at the Top Level of Your Worker!

Hi, it's Shii-chan!

Cloudflare Changelog developers.cloudflare.com

I found a small Workers update that gives you a bit more freedom in how you write code, so let me share it with you!

What was announced?

The Cloudflare Changelog announced a Workers runtime update.

During module evaluation, meaning the top level of your Worker module outside a request handler, these APIs no longer throw:

  • new AbortController()
  • AbortSignal.abort()
  • new WritableStream()
  • request.signal

The story so far

Until now, these APIs needed an active request context, and calling them at the top level threw an exception.

That meant you couldn't create one global AbortController and reuse it.

What changes

You can now create an AbortController at global scope without an error during module startup!

The signal can be observed and aborted across different requests, which makes it easier to coordinate cancellation in long-lived Workers such as Durable Objects.

Dive Deep

Here is the example from the changelog:

// This now works — no error during module startup
const controller = new AbortController();

export default {
  async fetch(request) {
    // The signal can be used across requests
    return new Response("OK", { signal: controller.signal });
  },
};

One thing to keep in mind: AbortSignal.timeout() still requires an active request context, because it needs to schedule a timer.

Wrap-up

  • AbortController and friends now work at the top level
  • This covers AbortSignal.abort(), new WritableStream() and request.signal too
  • Signals can be shared across requests, so cancellation is easier to coordinate in Durable Objects
  • AbortSignal.timeout() still needs a request context

This one is for anyone writing long-running Workers like Durable Objects!