cloudflare / cloudflare/workerd

🐛 Bug Report — Need a disconnect hook for streaming response

Open
#5,611 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
8.7k
Forks
739
Avg merge
2d 20h
Merged PRs (30d)
174

Description

According to the Workers documentation and examples, a Worker can return a ReadableStream in the fetch() handler to provide streaming responses. I’m trying to implement Server-Sent Events that periodically push data to the client, and log a message on the Worker when the client disconnects the GET request.

However, it seems impossible to detect when the client disconnects. The Worker runtime never notifies the ReadableStream returned in the response about the termination.

Below is a minimal reproduction:
```typescript
export default {
async fetch() {
const feedthroughStream = new TransformStream();
const writer = feedthroughStream.writable.getWriter();
await writer.ready;
const encoder = new TextEncoder();
let i = 0;
let timer = setInterval(async () => {
await writer.write(encoder.encode(`Value: ${i}\n`));
i++;

if (i >= 10) {
clearInterval(timer);
await writer.close();
}
}, 1000);
writer.closed.then(()=>console.log("writer.closed.then"));
writer.closed.catch(()=>console.log("writer.closed.catch"));
writer.closed.finally(()=>console.log("writer.closed.finally"));

return new Response(feedthroughStream.readable, {
status: 200,
headers: {
"X-Accel-Buffering": "no",
"Cache-Control": "no-store",
"Content-Type": "text/event-stream",
"Transfer-Encoding": "chunked",
}
});
}
}
```

When using `curl` on Linux, if I let the stream finish naturally, the Worker logs the expected `writer.closed.then` and `writer.closed.finally`.
But if I terminate `curl` early (client abort), no callbacks fire — the Worker runtime never closes the ReadableStream, so there is no way to detect client disconnect.

A similar issue has been reported here:

https://discord.com/channels/595317990191398933/1357179249152364614

It would be extremely helpful if Workers exposed a way to detect when a streaming response is aborted by the client, or automatically closed the ReadableStream.

Thanks!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.