-
Notifications
You must be signed in to change notification settings - Fork 458
Description
streamSSE abort signal not firing when client disconnects in Cloudflare Workers
Environment
- Hono version : 4.4.13
- Runtime : Cloudflare Workers
- hono / streaming :
streamSSE
Description
When usingstreamSSE in a Cloudflare Workers environment, the abort signal does not fire when the client disconnects from the SSE connection.This causes the server - side stream to continue running indefinitely, leading to:
- Continuous database queries even after client disconnect
- Wasted compute resources and CPU time
- Potential memory leaks in long - running connections
- No way to properly clean up resources
Current Behavior
import { Hono } from 'hono';
import { streamSSE } from 'hono/streaming';
const app = new Hono();
app.get('/sse', async (c) => {
return streamSSE(c, async (stream) => {
let isConnected = true;
// This event listener never fires when client disconnects
c.req.raw.signal.addEventListener('abort', () => {
console.log('Client disconnected'); // Never logs
isConnected = false;
});
// stream.onAbort also never fires
stream.onAbort(() => {
console.log('Aborted!'); // Never logs
});
while (isConnected) {
try {
// Database query continues running for hours after disconnect
const data = await checkDatabase();
if (data) {
await stream.writeSSE({
data: JSON.stringify(data),
event: 'update',
});
}
await stream.sleep(5000);
} catch (error) {
console.log('Error:', error); // Never catches disconnect
isConnected = false;
}
}
});
});
** What happens:**
- Client navigates away from page or closes connection
- Server - side loop continues running for 2 + hours
- No error is thrown, no abort signal fired
- Database continues being queried unnecessarily
- stream.aborted and stream.closed both return false even after client disconnects
Additional debugging output:
console.log(stream.aborted); // false (even after client closes)
console.log(stream.closed); // false (even after client closes)
// stream.onAbort callback also never fires
stream.onAbort(() => {
console.log('Aborted!'); // Never called
});
These properties continue to report false even after the client has closed the connection, and the onAbort callback is never invoked, providing no way to detect the disconnect.
Expected Behavior
When a client disconnects from an SSE connection:
- The
c.req.raw.signalabort event should fire - OR
stream.writeSSE()should throw an error when writing to a closed connection - OR provide an
onAbortcallback in thestreamSSEoptions
Any of these mechanisms would allow proper cleanup of resources.
Reproduction
- Create a Cloudflare Worker with the code above
- Connect from a client(browser or Ionic app):
const eventSource = new EventSource('/sse');- Wait for connection to establish
- Close the page or call
eventSource.close() - Observe server logs - no "Client disconnected" message appears
- Database queries continue for hours
Additional Context
This issue is particularly critical for:
- Real - time applications with frequent database polling
- Resource - intensive SSE endpoints
- Applications requiring proper cleanup(closing DB connections, clearing intervals, etc.)
The issue appears to be specific to Cloudflare Workers, as other runtimes may handle abort signals differently.