Async work stalls when another request wakes it
dleviminzi opened ·
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)
- BA
Thanks for the report, this has actually been fixed earlier last week and will be released in the next version.
bartlomiejureferenced 9c2d299dd6ablast month on GitHub
ryreferenced e519694581dclast month on GitHub
ryreferenced 4250d366aceblast month on GitHub
ryreferenced 3127cf8e307elast month on GitHub
ryreferenced 12d5b6333fe5last month on GitHub
Poggenreferenced this in v0.5.0: accepted cross-request work can be discarded during event retirement #207last month on GitHub
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