socketio / socket.io-postgres-adapter

The Socket.IO Postgres adapter, allowing to broadcast events between several Socket.IO servers
https://socket.io
MIT License
24 stars 8 forks source link

Shutting down adapter #13

Open michaelzangl opened 1 year ago

michaelzangl commented 1 year ago

I tried shutting down socket IO with the adapter installed. The node js process won't exit, since there are still timers active.

I expect this to work:

    socketIo.close();

There are still two timers running afterwards: the 30s cleanup timer and the ~2s reconnect timer

The workaround I found is:

    await socketIo.of('/').adapter.close(); // < this will clean the 30s cleanup timer
    socketIo.close();
    pool.connect = () => new Promise(() => {}); // < this will make the reconnect timer get blocked forever on the first reconnect attempt.
grobarko commented 2 months ago

The fix (https://github.com/socketio/socket.io/commit/bf64870957e626a73e0544716a1a41a4ba5093bb) still isn't working.

Currently I'm using this as a workaround:

await io.of('/').adapter.close();

io.close(() => {
  console.log("Server terminated gracefully 👌");
});
await pool.end();
darrachequesne commented 2 months ago

@grobarko I was not able to reproduce the issue:

import { Server } from "socket.io";
import { createAdapter } from "@socket.io/postgres-adapter";
import pg from "pg";
import process from "node:process";

const PORT = process.env.PORT || 3000;

const pool = new pg.Pool({
  user: "postgres",
  host: "localhost",
  database: "postgres",
  password: "changeit",
  port: 5432,
});

await pool.query(`
  CREATE TABLE IF NOT EXISTS socket_io_attachments (
      id          bigserial UNIQUE,
      created_at  timestamptz DEFAULT NOW(),
      payload     bytea
  );
`);

pool.on("error", (err) => {
  console.error("Postgres error", err);
});

const io = new Server({
  adapter: createAdapter(pool)
});

io.on("connection", (socket) => {
  socket.on("hello", () => {
    // send to anyone except the sender
    socket.broadcast.emit("hello", socket.id, process.pid);
  });
});

io.listen(PORT);
console.log(`server listening on port ${PORT}`);

setTimeout(async () => {
  console.log("STOP !!!");

  io.close();
  await pool.end();
}, 1000);

See example here: https://github.com/socketio/socket.io/tree/main/examples/postgres-adapter-example

Calling io.close() seems sufficient (with pool.end(), but that makes sense since we don't own that object). Could you please check?