Skip to content

Graceful exit - onClose hook is never called when connections are active #45

@franky47

Description

@franky47

🐛 Bug Report

I'm trying to setup a graceful exit strategy by closing connections to other services (eg: database, redis cache) in an onClose hook, using fastify-graceful-shutdown.

However, when there are active websocket connections, the onClose hooks are never called, even though fastify.close() was called upon reception of the exit signal by fastify-graceful-shutdown.

This is probably linked to the fact that graceful shutdown waits for requests to complete (while refusing new ones, which works ok), and websocket requests never actually complete on their own..

To Reproduce

Using this example on CodeSandbox:

  1. The server should start automatically
  2. Run the client code locally (see below), the client stays connected.
  3. Restart the server in CodeSandbox using the Server Control Panel > Control Container > Restart Server button.
  4. Observe the logs: the onClose log line is not printed out.

Server code:

const Fastify = require("fastify");

const server = Fastify({ logger: true });

// The order does not seem to matter here:
server.register(require("fastify-graceful-shutdown"));
server.register(require("fastify-websocket"));

server.get("/foo", { websocket: true }, (connection, req) => {
  const socketID = req.headers["sec-websocket-key"];
  server.log.info({
    msg: "Client connected",
    socket: socketID
  });
  connection.socket.on("message", message => {
    server.log.info({
      msg: message,
      socket: socketID
    });
  });
  connection.socket.on("close", () => {
    server.log.info({
      msg: "Client disconnected",
      socket: socketID
    });
  });
});

server.addHook("onClose", (server, done) => {
  server.log.info("in the onClose hook");
  done();
});

server.listen({ port: 8080 });

Test client code:

const WebSocket = require('isomorphic-ws')

const client = new WebSocket('wss://uvgpw.sse.codesandbox.io/foo')

client.on('open', () => {
  console.log('Connected')
  client.send('foo')
})

client.on('close', () => {
  console.log('Disconnected')
})

Expected behavior

The onClose hook should be called when fastify.close() is called.

Closing the open websocket connections could be done manually here using whatever strategy makes sense for the app (sending a batch of data, a special message to the client before closing the connection...).

Your Environment

  • node version: 13.7.0
  • fastify version: 2.11.0
  • os: macOS
  • fastify-graceful-shutdown: 2.0.1
  • fastify-websocket: 1.1.0

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