Graceful Shutdown Process
Colyseus listens for SIGTERM
and SIGINT
signals to gracefully shut down the process.
These actions will be performed, in order, before the process is killed:
Server: On Before Shutdown
The custom gameServer.onBeforeShutdown()
is called, if defined.
gameServer.onBeforeShutdown(async () => {
// (...) custom logic
});
Process is excluded from match-making.
The process is not going to be selected for new room creations anymore.
Rooms are locked
The rooms handled by this process are locked via room.lock()
.
Room: On Before Shutdown
All rooms room.onBeforeShutdown()
is called.
You may override this method to perform custom actions that will result in the room being disposed in a few minutes. By default, it simply calls room.disconnect()
, which will trigger room.onLeave()
for all clients, and then room.onDispose()
almost immediately.
onBeforeShutdown() {
//
// Notify users that process is shutting down, they may need to save their progress and join a new room
//
this.broadcast("going-down", "Server is shutting down. Please save your progress and join a new room.");
//
// Disconnect all clients after 5 minutes
//
this.clock.setTimeout(() => this.disconnect(), 5 * 60 * 1000);
}
(…) wait until all rooms are disposed
The server waits for local room count to be zero before proceeding to the next step.
Close Transport, Presence, and Driver
The Transport, Presence, and Driver are closed and disconnected.
Server: On Shutdown
The custom gameServer.onShutdown()
is called, if defined.
At this point there is no more rooms or clients connected to the server.
gameServer.onShutdown(async () => {
// (...) custom logic
});
Process is killed
The process is killed after all the steps above are completed.
You may use async
functions or return a Promise
to perform asynchronous operations on onLeave
and onDispose
methods, as well as gameServer.onBeforeShutdown()
and gameServer.onShutdown()
.
By returning a Promise
, the server will wait for them to be completed before killing the worker process.
import { Room } from "colyseus";
class MyRoom extends Room {
onLeave (client) {
return new Promise((resolve, reject) => {
doDatabaseOperation((err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
onDispose () {
return new Promise((resolve, reject) => {
doDatabaseOperation((err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
}