feat(admin): pousse le monitoring en WebSocket au lieu du polling client #45
1 changed files with 16 additions and 1 deletions
|
|
@ -51,6 +51,15 @@ function waitForEvent<T>(socket: ClientSocket, event: string, timeoutMs = 1500):
|
||||||
describe("Admin monitoring — WebSocket push", () => {
|
describe("Admin monitoring — WebSocket push", () => {
|
||||||
let baseUrl: string;
|
let baseUrl: string;
|
||||||
let broadcast: MonitoringBroadcastService;
|
let broadcast: MonitoringBroadcastService;
|
||||||
|
// Hoisted to suite scope (not a local in `before`) so `after` can shut
|
||||||
|
// it down. `broadcast.stop()` alone only clears the probe interval — the
|
||||||
|
// socket.io server keeps engine.io's ping timers and the listening
|
||||||
|
// http.Server (port 0) alive, and Mocha runs without `--exit`
|
||||||
|
// (`.mocharc.json`), so that one leaked handle stops the whole process
|
||||||
|
// from ever draining once the last test passes. That is exactly what
|
||||||
|
// stalled CI: the `test` job printed "N passing" and then hung for
|
||||||
|
// hours until the runner was killed.
|
||||||
|
let io: SocketIoServer;
|
||||||
const clientSockets: ClientSocket[] = [];
|
const clientSockets: ClientSocket[] = [];
|
||||||
|
|
||||||
// A real listening server, not just createApp()'s bare Express instance
|
// A real listening server, not just createApp()'s bare Express instance
|
||||||
|
|
@ -60,7 +69,7 @@ describe("Admin monitoring — WebSocket push", () => {
|
||||||
// free one, so this suite never collides with anything else listening.
|
// free one, so this suite never collides with anything else listening.
|
||||||
before(async () => {
|
before(async () => {
|
||||||
const httpServer = createServer().httpServer;
|
const httpServer = createServer().httpServer;
|
||||||
const io = new SocketIoServer(httpServer, { cors: { origin: "*" } });
|
io = new SocketIoServer(httpServer, { cors: { origin: "*" } });
|
||||||
broadcast = new MonitoringBroadcastService(io);
|
broadcast = new MonitoringBroadcastService(io);
|
||||||
await new Promise<void>((resolve) => httpServer.listen(0, resolve));
|
await new Promise<void>((resolve) => httpServer.listen(0, resolve));
|
||||||
const { port } = httpServer.address() as AddressInfo;
|
const { port } = httpServer.address() as AddressInfo;
|
||||||
|
|
@ -70,6 +79,12 @@ describe("Admin monitoring — WebSocket push", () => {
|
||||||
|
|
||||||
after(async () => {
|
after(async () => {
|
||||||
broadcast.stop();
|
broadcast.stop();
|
||||||
|
// Disconnects any socket still open, stops engine.io's timers, and
|
||||||
|
// closes the http.Server socket.io was attached to — without this the
|
||||||
|
// suite never lets Node's event loop drain (see the `io` field's note).
|
||||||
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
io.close((err) => (err ? reject(err) : resolve()));
|
||||||
|
});
|
||||||
await prisma.$disconnect();
|
await prisma.$disconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue