uNetworking / uWebSockets.js

μWebSockets for Node.js back-ends :metal:
Apache License 2.0
7.86k stars 569 forks source link

app.close() #794

Closed jjjuk closed 1 year ago

jjjuk commented 2 years ago

Hello dear contributors! Please make simple app.close(). I use uWS as api gateway, when service restarts app doesn't close. uWS.us_listen_socket_close(listenSocket) doesn't help. After restart port is busy. I love this project, but this is ridiculous. Or any thoughts how to overcome this? I use moleculer for microservices

jjjuk commented 2 years ago

uNetworking/uWebSockets#1529 copy of this, I know. Need your attention to this problem

e3dio commented 2 years ago

This is how you graceful close app + websockets:

import { App, us_listen_socket_close } from 'uWebSockets.js';

const wsMap = new Map();
let id = 0;

const port = 8002;
let listenSocket;

const app = App()
   .get('/', res => res.end('123'))
   .ws('/', {
      open: ws => {
         ws.id = ++id;
         wsMap.set(ws.id, ws);
         console.log('open', ws.id);
      },
      close: (ws, code) => {
         wsMap.delete(ws.id);
         console.log('close', ws.id, code);
      }  
   })
   .listen(port, s => {
      listenSocket = s;
      if (s) console.log('listening on', port);
      else console.log('failed to listen on', port);
   });

const shutdown = () => {
   if (listenSocket) us_listen_socket_close(listenSocket); // close listen socket for new http and ws connections
   listenSocket = null;
   wsMap.forEach(ws => ws.close()); // immediate close all websockets
   // ws.end(code) - potentially takes 4 to 16 seconds to graceful close websocket (depends on idletimeout)
};

Other than websockets, Http connection can keep app open for up to 10 seconds (http timeout) and if you have response.onData() set it is extended 10 seconds every onData event. If you want to close requests you can track open requests and close like websockets openRequests = new Set(); openRequests.forEach(r => r.close()). Or process.exit() also works. app.close() could be shortcut to close all sockets

jjjuk commented 2 years ago

Thank you for answer, but there wasn't any problem to stop the process, there was a problem to reload local service (one process runs multiple local services), after reload requests don't reach the server.

I fixed this by running the server with fork, and killing process on service restart. I'll try to reproduce this problem outside of moleculer. But basically it seems like if you stop server gracefully and run it again in the same process it wouldn't be available.

I work on windows so maybe after graceful stop port is still busy.

e3dio commented 2 years ago

Linux has no issue with close and re-open on same port in same process, looks like does not work in Windows, recommend running Linux if you need that