Skip to content

πŸ› Bug Report β€” Need a disconnect hook for streaming responseΒ #5611

@rikka0w0

Description

@rikka0w0

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:

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions