denoland/celldPublic

self-hosted, distributed Durable Objects

Async work stalls when another request wakes it

DL

I ran into this on celld 0.4.1 while using Flue. When one request wakes async work started by another, that work can stall after the waking request finishes. This affects streams and background tasks.

To reproduce, deploy this Worker with a Durable Object binding named `PROBE` for `StreamProbe`:

```js import { DurableObject } from "cloudflare:workers";

export class StreamProbe extends DurableObject { phase = "idle";

fetch(request) { const path = new URL(request.url).pathname; if (path === "/start") { this.ctx.waitUntil((async () => { await new Promise(resolve => { this.notify = resolve; }); this.phase = "resumed"; await new Promise(resolve => setTimeout(resolve, 100)); this.phase = "completed"; })()); return new Response("admitted"); } if (path === "/notify") { this.notify(); return new Response("notified"); } return Response.json({ phase: this.phase }); } }

export default { fetch(request, env) { return env.PROBE.get(env.PROBE.idFromName("probe")).fetch(request); } }; ```

Set `CELLD_URL` to the Worker’s URL, then run:

```sh curl -fsS -X POST "$CELLD_URL/start" curl -fsS -X POST "$CELLD_URL/notify" sleep 2 curl -fsS "$CELLD_URL/stats" ```

Expected: `{"phase":"completed"}`. On 0.4.1 it stays at `{"phase":"resumed"}`—the task never gets past the 100 ms timeout.

The same pattern in a `ReadableStream` producer leaves readers stuck after the first chunk.

Here is an attempt at a patch that fixes it. Works for me, but there might be some other approach that is best

[0001-Fix-cross-request-async-operation-lifetimes.patch](https://github.com/user-attachments/files/32165011/0001-Fix-cross-request-async-operation-lifetimes.patch)

  1. BA

    Thanks for the report, this has actually been fixed earlier last week and will be released in the next version.

  2. bartlomiejuclosedlast month on GitHub

  3. bartlomiejureferenced 9c2d299dd6ablast month on GitHub

  4. ryreferenced e519694581dclast month on GitHub

  5. ryreferenced 4250d366aceblast month on GitHub

  6. ryreferenced 3127cf8e307elast month on GitHub

  7. ryreferenced 12d5b6333fe5last month on GitHub

  8. Poggenreferenced this in v0.5.0: accepted cross-request work can be discarded during event retirement #207last month on GitHub

  9. hmkreferenced this in Durable Object: an outbound call from a continuation of an ended request, woken by another event, never settles #258last month on GitHub