Version: Deno 2.2.12 I'm experiencing an issue where a WebSocket server prevents the Deno process from exiting properly. Even after adding signal listeners for SIGINT and SIGTERM, and awaiting server.finished, the process stays alive if there are active WebSocket clients. Here's a minimal example: ```ts const abort = new AbortController(); function graceful() { abort.abort(); console.log("Graceful shutdown initiated."); // close db and others } const server = Deno.serve({ signal: abort.signal }, async (req) => { const { socket, response } = Deno.upgradeWebSocket(req); socket.addEventListener('open', () => {}); socket.addEventListener('message', () => {}); socket.addEventListener('close', () => {}); socket.addEventListener('error', () => {}); return response; }); Deno.addSignalListener('SIGINT', graceful); Deno.addSignalListener('SIGTERM', graceful); server.finished.finally(() => { console.debug(`\nListening stopped on http://${server.addr.hostname}:${server.addr.port}/`); // Deno.exit(); // Without this line, the process doesn't exit on its own. }); ``` #### Expected behavior: When sending a Ctrl+C (SIGINT) or the process receives SIGTERM, the server should close and the Deno process should exit automatically. #### Actual behavior: The server stops accepting new connections. However, the Deno process remains alive as long as there are active WebSocket clients. Neither SIGINT nor SIGTERM fully terminates the process. It only exits if I explicitly call Deno.exit(). #### Additional notes: It seems that active WebSocket connections keep the process alive even after server.close() and server.finished. #### Question: Is this the expected behavior? Is there a recommended way to cleanly terminate all WebSocket connections so the process can exit naturally without needing Deno.exit()? #### Workaround found: Manually tracking and closing all WebSocket connections when shutting down allows the process to exit cleanly. Example: ```ts const abort = new AbortController(); const sockets = new Set<WebSocket>(); const graceful = async (): Promise<void> => { abort.abort(); sockets.forEach((socket) => socket.close()); }; const server = Deno.serve({ signal: abort.signal }, async (req) => { const { socket, response } = Deno.upgradeWebSocket(req); socket.addEventListener('open', () => { sockets.add(socket); }); socket.addEventListener('message', (record) => {}); socket.addEventListener('close', () => { if(sockets.has(socket)){ sockets.delete(socket) } }); socket.addEventListener('error', () => {}); return response; }); Deno.addSignalListener('SIGINT', graceful); Deno.addSignalListener('SIGTERM', graceful); server.finished.finally(() => { console.debug(`\nListening stopped on http://${server.addr.hostname}:${server.addr.port}/`); }); ```
This issue appears to be discussing a feature request or bug report related to the repository. Based on the content, it seems to be still under discussion. The issue was opened by tghpereira and has received 0 comments.