WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

streamSSE abort signal not firing when client disconnects in Cloudflare Workers #769

@Rahul-codoffer

Description

@Rahul-codoffer

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:

  1. Continuous database queries even after client disconnect
  2. Wasted compute resources and CPU time
  3. Potential memory leaks in long - running connections
  4. 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:

  1. The c.req.raw.signal abort event should fire
  2. OR stream.writeSSE() should throw an error when writing to a closed connection
  3. OR provide an onAbort callback in thestreamSSE options

Any of these mechanisms would allow proper cleanup of resources.

Reproduction

  1. Create a Cloudflare Worker with the code above
  2. Connect from a client(browser or Ionic app):
const eventSource = new EventSource('/sse');
  1. Wait for connection to establish
  2. Close the page or calleventSource.close()
  3. Observe server logs - no "Client disconnected" message appears
  4. 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.

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