@colyseus/core 0.16.0-preview.9 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/build/Debug.js +6 -2
- package/build/Debug.js.map +2 -2
- package/build/Debug.mjs +11 -10
- package/build/Debug.mjs.map +2 -2
- package/build/IPC.d.ts +1 -1
- package/build/IPC.js +3 -3
- package/build/IPC.js.map +2 -2
- package/build/IPC.mjs +4 -3
- package/build/IPC.mjs.map +2 -2
- package/build/Logger.mjs +4 -3
- package/build/Logger.mjs.map +1 -1
- package/build/MatchMaker.d.ts +35 -30
- package/build/MatchMaker.js +150 -100
- package/build/MatchMaker.js.map +2 -2
- package/build/MatchMaker.mjs +154 -107
- package/build/MatchMaker.mjs.map +2 -2
- package/build/Protocol.d.ts +3 -4
- package/build/Protocol.js +33 -19
- package/build/Protocol.js.map +2 -2
- package/build/Protocol.mjs +36 -21
- package/build/Protocol.mjs.map +2 -2
- package/build/Room.d.ts +64 -40
- package/build/Room.js +408 -151
- package/build/Room.js.map +2 -2
- package/build/Room.mjs +412 -158
- package/build/Room.mjs.map +2 -2
- package/build/Server.d.ts +8 -7
- package/build/Server.js +51 -18
- package/build/Server.js.map +2 -2
- package/build/Server.mjs +51 -21
- package/build/Server.mjs.map +3 -3
- package/build/Stats.d.ts +2 -0
- package/build/Stats.js +38 -3
- package/build/Stats.js.map +2 -2
- package/build/Stats.mjs +30 -6
- package/build/Stats.mjs.map +2 -2
- package/build/Transport.d.ts +8 -7
- package/build/Transport.js +1 -1
- package/build/Transport.js.map +2 -2
- package/build/Transport.mjs +6 -5
- package/build/Transport.mjs.map +2 -2
- package/build/discovery/index.d.ts +1 -1
- package/build/discovery/index.js.map +2 -2
- package/build/discovery/index.mjs +3 -2
- package/build/discovery/index.mjs.map +2 -2
- package/build/errors/RoomExceptions.d.ts +39 -0
- package/build/errors/RoomExceptions.js +100 -0
- package/build/errors/RoomExceptions.js.map +7 -0
- package/build/errors/RoomExceptions.mjs +71 -0
- package/build/errors/RoomExceptions.mjs.map +7 -0
- package/build/errors/SeatReservationError.mjs +3 -2
- package/build/errors/SeatReservationError.mjs.map +1 -1
- package/build/errors/ServerError.js +1 -1
- package/build/errors/ServerError.js.map +1 -1
- package/build/errors/ServerError.mjs +5 -4
- package/build/errors/ServerError.mjs.map +2 -2
- package/build/index.d.ts +21 -19
- package/build/index.js +47 -20
- package/build/index.js.map +2 -2
- package/build/index.mjs +41 -19
- package/build/index.mjs.map +2 -2
- package/build/matchmaker/Lobby.d.ts +3 -3
- package/build/matchmaker/Lobby.js +6 -3
- package/build/matchmaker/Lobby.js.map +2 -2
- package/build/matchmaker/Lobby.mjs +4 -4
- package/build/matchmaker/Lobby.mjs.map +2 -2
- package/build/matchmaker/RegisteredHandler.d.ts +6 -7
- package/build/matchmaker/RegisteredHandler.js +7 -10
- package/build/matchmaker/RegisteredHandler.js.map +2 -2
- package/build/matchmaker/RegisteredHandler.mjs +11 -13
- package/build/matchmaker/RegisteredHandler.mjs.map +2 -2
- package/build/matchmaker/controller.d.ts +4 -5
- package/build/matchmaker/controller.js +22 -15
- package/build/matchmaker/controller.js.map +2 -2
- package/build/matchmaker/controller.mjs +19 -13
- package/build/matchmaker/controller.mjs.map +2 -2
- package/build/matchmaker/driver/api.d.ts +104 -0
- package/build/matchmaker/driver/api.js +29 -0
- package/build/matchmaker/driver/api.js.map +7 -0
- package/build/matchmaker/driver/api.mjs +7 -0
- package/build/matchmaker/driver/api.mjs.map +7 -0
- package/build/matchmaker/driver/index.d.ts +2 -2
- package/build/matchmaker/driver/index.js +2 -2
- package/build/matchmaker/driver/index.js.map +2 -2
- package/build/matchmaker/driver/index.mjs +5 -4
- package/build/matchmaker/driver/index.mjs.map +2 -2
- package/build/matchmaker/driver/local/LocalDriver.d.ts +13 -0
- package/build/matchmaker/driver/local/LocalDriver.js +65 -0
- package/build/matchmaker/driver/local/LocalDriver.js.map +7 -0
- package/build/matchmaker/driver/local/LocalDriver.mjs +43 -0
- package/build/matchmaker/driver/local/LocalDriver.mjs.map +7 -0
- package/build/matchmaker/driver/local/Query.d.ts +9 -0
- package/build/matchmaker/driver/local/Query.js +78 -0
- package/build/matchmaker/driver/local/Query.js.map +7 -0
- package/build/matchmaker/driver/local/Query.mjs +56 -0
- package/build/matchmaker/driver/local/Query.mjs.map +7 -0
- package/build/matchmaker/driver/local/RoomData.d.ts +19 -0
- package/build/matchmaker/driver/local/RoomData.js +79 -0
- package/build/matchmaker/driver/local/RoomData.js.map +7 -0
- package/build/matchmaker/driver/local/RoomData.mjs +57 -0
- package/build/matchmaker/driver/local/RoomData.mjs.map +7 -0
- package/build/presence/LocalPresence.d.ts +10 -6
- package/build/presence/LocalPresence.js +85 -24
- package/build/presence/LocalPresence.js.map +3 -3
- package/build/presence/LocalPresence.mjs +85 -27
- package/build/presence/LocalPresence.mjs.map +3 -3
- package/build/presence/Presence.d.ts +38 -2
- package/build/presence/Presence.js.map +1 -1
- package/build/rooms/LobbyRoom.d.ts +6 -6
- package/build/rooms/LobbyRoom.js +8 -3
- package/build/rooms/LobbyRoom.js.map +2 -2
- package/build/rooms/LobbyRoom.mjs +7 -5
- package/build/rooms/LobbyRoom.mjs.map +2 -2
- package/build/rooms/RelayRoom.d.ts +3 -3
- package/build/rooms/RelayRoom.js +3 -1
- package/build/rooms/RelayRoom.js.map +2 -2
- package/build/rooms/RelayRoom.mjs +10 -7
- package/build/rooms/RelayRoom.mjs.map +2 -2
- package/build/serializer/NoneSerializer.d.ts +2 -2
- package/build/serializer/NoneSerializer.js.map +1 -1
- package/build/serializer/NoneSerializer.mjs +3 -2
- package/build/serializer/NoneSerializer.mjs.map +2 -2
- package/build/serializer/SchemaSerializer.d.ts +16 -15
- package/build/serializer/SchemaSerializer.js +12 -10
- package/build/serializer/SchemaSerializer.js.map +2 -2
- package/build/serializer/SchemaSerializer.mjs +16 -13
- package/build/serializer/SchemaSerializer.mjs.map +2 -2
- package/build/serializer/SchemaSerializerDebug.d.ts +7 -0
- package/build/serializer/SchemaSerializerDebug.js +0 -0
- package/build/serializer/SchemaSerializerDebug.js.map +7 -0
- package/build/serializer/SchemaSerializerDebug.mjs +0 -0
- package/build/serializer/SchemaSerializerDebug.mjs.map +7 -0
- package/build/serializer/Serializer.d.ts +1 -2
- package/build/serializer/Serializer.js.map +1 -1
- package/build/utils/DevMode.d.ts +2 -2
- package/build/utils/DevMode.js +8 -4
- package/build/utils/DevMode.js.map +2 -2
- package/build/utils/DevMode.mjs +7 -6
- package/build/utils/DevMode.mjs.map +2 -2
- package/build/utils/Utils.d.ts +8 -3
- package/build/utils/Utils.js +41 -17
- package/build/utils/Utils.js.map +2 -2
- package/build/utils/Utils.mjs +40 -21
- package/build/utils/Utils.mjs.map +2 -2
- package/package.json +17 -6
package/build/MatchMaker.js
CHANGED
|
@@ -17,6 +17,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
return to;
|
|
18
18
|
};
|
|
19
19
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
20
24
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
21
25
|
mod
|
|
22
26
|
));
|
|
@@ -25,7 +29,6 @@ var MatchMaker_exports = {};
|
|
|
25
29
|
__export(MatchMaker_exports, {
|
|
26
30
|
MatchMakerState: () => MatchMakerState,
|
|
27
31
|
accept: () => accept,
|
|
28
|
-
cleanupStaleRooms: () => cleanupStaleRooms,
|
|
29
32
|
controller: () => import_controller.default,
|
|
30
33
|
create: () => create,
|
|
31
34
|
createRoom: () => createRoom,
|
|
@@ -34,6 +37,7 @@ __export(MatchMaker_exports, {
|
|
|
34
37
|
driver: () => driver,
|
|
35
38
|
findOneRoomAvailable: () => findOneRoomAvailable,
|
|
36
39
|
getHandler: () => getHandler,
|
|
40
|
+
getLocalRoomById: () => getLocalRoomById,
|
|
37
41
|
getRoomById: () => getRoomById,
|
|
38
42
|
getRoomClass: () => getRoomClass,
|
|
39
43
|
gracefullyShutdown: () => gracefullyShutdown,
|
|
@@ -41,7 +45,6 @@ __export(MatchMaker_exports, {
|
|
|
41
45
|
hasHandler: () => hasHandler,
|
|
42
46
|
healthCheckAllProcesses: () => healthCheckAllProcesses,
|
|
43
47
|
healthCheckProcessId: () => healthCheckProcessId,
|
|
44
|
-
isGracefullyShuttingDown: () => isGracefullyShuttingDown,
|
|
45
48
|
join: () => join,
|
|
46
49
|
joinById: () => joinById,
|
|
47
50
|
joinOrCreate: () => joinOrCreate,
|
|
@@ -55,34 +58,41 @@ __export(MatchMaker_exports, {
|
|
|
55
58
|
removeRoomType: () => removeRoomType,
|
|
56
59
|
reserveSeatFor: () => reserveSeatFor,
|
|
57
60
|
selectProcessIdToCreateRoom: () => selectProcessIdToCreateRoom,
|
|
61
|
+
setHealthChecksEnabled: () => setHealthChecksEnabled,
|
|
58
62
|
setup: () => setup,
|
|
59
63
|
state: () => state,
|
|
60
64
|
stats: () => stats
|
|
61
65
|
});
|
|
62
66
|
module.exports = __toCommonJS(MatchMaker_exports);
|
|
63
|
-
var
|
|
64
|
-
var
|
|
65
|
-
var
|
|
66
|
-
var
|
|
67
|
-
var
|
|
68
|
-
var
|
|
69
|
-
var
|
|
70
|
-
var
|
|
71
|
-
var
|
|
72
|
-
var
|
|
73
|
-
var
|
|
74
|
-
var
|
|
75
|
-
var
|
|
76
|
-
var
|
|
77
|
-
var
|
|
67
|
+
var import_events = require("events");
|
|
68
|
+
var import_Protocol = require("./Protocol.js");
|
|
69
|
+
var import_IPC = require("./IPC.js");
|
|
70
|
+
var import_Utils = require("./utils/Utils.js");
|
|
71
|
+
var import_DevMode = require("./utils/DevMode.js");
|
|
72
|
+
var import_RegisteredHandler = require("./matchmaker/RegisteredHandler.js");
|
|
73
|
+
var import_Room = require("./Room.js");
|
|
74
|
+
var import_LocalPresence = require("./presence/LocalPresence.js");
|
|
75
|
+
var import_Debug = require("./Debug.js");
|
|
76
|
+
var import_SeatReservationError = require("./errors/SeatReservationError.js");
|
|
77
|
+
var import_ServerError = require("./errors/ServerError.js");
|
|
78
|
+
var import_LocalDriver = require("./matchmaker/driver/local/LocalDriver.js");
|
|
79
|
+
var import_controller = __toESM(require("./matchmaker/controller.js"));
|
|
80
|
+
var stats = __toESM(require("./Stats.js"));
|
|
81
|
+
var import_Logger = require("./Logger.js");
|
|
82
|
+
var import_discovery = require("./discovery/index.js");
|
|
83
|
+
var import_api = require("./matchmaker/driver/api.js");
|
|
78
84
|
const handlers = {};
|
|
79
85
|
const rooms = {};
|
|
86
|
+
const events = new import_events.EventEmitter();
|
|
80
87
|
let publicAddress;
|
|
81
88
|
let processId;
|
|
82
89
|
let presence;
|
|
83
90
|
let driver;
|
|
84
91
|
let selectProcessIdToCreateRoom;
|
|
85
|
-
let
|
|
92
|
+
let enableHealthChecks = true;
|
|
93
|
+
function setHealthChecksEnabled(value) {
|
|
94
|
+
enableHealthChecks = value;
|
|
95
|
+
}
|
|
86
96
|
let onReady = new import_Utils.Deferred();
|
|
87
97
|
var MatchMakerState = /* @__PURE__ */ ((MatchMakerState2) => {
|
|
88
98
|
MatchMakerState2[MatchMakerState2["INITIALIZING"] = 0] = "INITIALIZING";
|
|
@@ -95,10 +105,9 @@ async function setup(_presence, _driver, _publicAddress, _selectProcessIdToCreat
|
|
|
95
105
|
if (onReady === void 0) {
|
|
96
106
|
onReady = new import_Utils.Deferred();
|
|
97
107
|
}
|
|
98
|
-
isGracefullyShuttingDown = false;
|
|
99
108
|
state = 0 /* INITIALIZING */;
|
|
100
109
|
presence = _presence || new import_LocalPresence.LocalPresence();
|
|
101
|
-
driver = _driver || new
|
|
110
|
+
driver = _driver || new import_LocalDriver.LocalDriver();
|
|
102
111
|
publicAddress = _publicAddress;
|
|
103
112
|
stats.reset(false);
|
|
104
113
|
if (import_DevMode.isDevMode) {
|
|
@@ -121,25 +130,44 @@ async function accept() {
|
|
|
121
130
|
return handleCreateRoom.apply(void 0, args);
|
|
122
131
|
}
|
|
123
132
|
});
|
|
124
|
-
|
|
133
|
+
if (enableHealthChecks) {
|
|
134
|
+
await healthCheckAllProcesses();
|
|
135
|
+
stats.setAutoPersistInterval();
|
|
136
|
+
}
|
|
125
137
|
state = 1 /* READY */;
|
|
126
138
|
await stats.persist();
|
|
127
139
|
if (import_DevMode.isDevMode) {
|
|
128
140
|
await (0, import_DevMode.reloadFromCache)();
|
|
129
141
|
}
|
|
130
142
|
}
|
|
131
|
-
async function joinOrCreate(roomName, clientOptions = {},
|
|
143
|
+
async function joinOrCreate(roomName, clientOptions = {}, authContext) {
|
|
132
144
|
return await (0, import_Utils.retry)(async () => {
|
|
133
|
-
const authData = await callOnAuth(roomName,
|
|
145
|
+
const authData = await callOnAuth(roomName, clientOptions, authContext);
|
|
134
146
|
let room = await findOneRoomAvailable(roomName, clientOptions);
|
|
135
147
|
if (!room) {
|
|
136
|
-
|
|
148
|
+
const handler = getHandler(roomName);
|
|
149
|
+
const filterOptions = handler.getFilterOptions(clientOptions);
|
|
150
|
+
const concurrencyKey = (0, import_api.getLockId)(filterOptions);
|
|
151
|
+
await concurrentJoinOrCreateRoomLock(handler, concurrencyKey, async (roomId) => {
|
|
152
|
+
if (roomId) {
|
|
153
|
+
room = await driver.findOne({ roomId });
|
|
154
|
+
}
|
|
155
|
+
if (!room) {
|
|
156
|
+
room = await findOneRoomAvailable(roomName, clientOptions);
|
|
157
|
+
}
|
|
158
|
+
if (!room) {
|
|
159
|
+
room = await createRoom(roomName, clientOptions);
|
|
160
|
+
presence.lpush(`l:${handler.name}:${concurrencyKey}`, room.roomId);
|
|
161
|
+
presence.expire(`l:${handler.name}:${concurrencyKey}`, import_Utils.MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME * 2);
|
|
162
|
+
}
|
|
163
|
+
return room;
|
|
164
|
+
});
|
|
137
165
|
}
|
|
138
166
|
return await reserveSeatFor(room, clientOptions, authData);
|
|
139
167
|
}, 5, [import_SeatReservationError.SeatReservationError]);
|
|
140
168
|
}
|
|
141
|
-
async function create(roomName, clientOptions = {},
|
|
142
|
-
const authData = await callOnAuth(roomName,
|
|
169
|
+
async function create(roomName, clientOptions = {}, authContext) {
|
|
170
|
+
const authData = await callOnAuth(roomName, clientOptions, authContext);
|
|
143
171
|
const room = await createRoom(roomName, clientOptions);
|
|
144
172
|
return reserveSeatFor(room, clientOptions, authData);
|
|
145
173
|
}
|
|
@@ -187,23 +215,21 @@ async function joinById(roomId, clientOptions = {}, authOptions) {
|
|
|
187
215
|
const authData = await callOnAuth(room.name, authOptions);
|
|
188
216
|
return reserveSeatFor(room, clientOptions, authData);
|
|
189
217
|
}
|
|
190
|
-
async function query(conditions = {}) {
|
|
191
|
-
return await driver.
|
|
192
|
-
}
|
|
193
|
-
async function findOneRoomAvailable(roomName,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return await roomQuery;
|
|
206
|
-
});
|
|
218
|
+
async function query(conditions = {}, sortOptions) {
|
|
219
|
+
return await driver.query(conditions, sortOptions);
|
|
220
|
+
}
|
|
221
|
+
async function findOneRoomAvailable(roomName, filterOptions, additionalSortOptions) {
|
|
222
|
+
const handler = getHandler(roomName);
|
|
223
|
+
const sortOptions = Object.assign({}, handler.sortOptions ?? {});
|
|
224
|
+
if (additionalSortOptions) {
|
|
225
|
+
Object.assign(sortOptions, additionalSortOptions);
|
|
226
|
+
}
|
|
227
|
+
return await driver.findOne({
|
|
228
|
+
locked: false,
|
|
229
|
+
name: roomName,
|
|
230
|
+
private: false,
|
|
231
|
+
...handler.getFilterOptions(filterOptions)
|
|
232
|
+
}, sortOptions);
|
|
207
233
|
}
|
|
208
234
|
async function remoteRoomCall(roomId, method, args, rejectionTimeout = import_Utils.REMOTE_ROOM_SHORT_TIMEOUT) {
|
|
209
235
|
const room = rooms[roomId];
|
|
@@ -225,23 +251,17 @@ async function remoteRoomCall(roomId, method, args, rejectionTimeout = import_Ut
|
|
|
225
251
|
}
|
|
226
252
|
}
|
|
227
253
|
function defineRoomType(roomName, klass, defaultOptions) {
|
|
228
|
-
const registeredHandler = new import_RegisteredHandler.RegisteredHandler(klass, defaultOptions);
|
|
254
|
+
const registeredHandler = new import_RegisteredHandler.RegisteredHandler(roomName, klass, defaultOptions);
|
|
229
255
|
handlers[roomName] = registeredHandler;
|
|
230
256
|
if (klass.prototype["onAuth"] !== import_Room.Room.prototype["onAuth"]) {
|
|
231
257
|
if (klass["onAuth"] !== import_Room.Room["onAuth"]) {
|
|
232
258
|
import_Logger.logger.info(`\u274C "${roomName}"'s onAuth() defined at the instance level will be ignored.`);
|
|
233
259
|
}
|
|
234
260
|
}
|
|
235
|
-
if (!import_DevMode.isDevMode) {
|
|
236
|
-
cleanupStaleRooms(roomName);
|
|
237
|
-
}
|
|
238
261
|
return registeredHandler;
|
|
239
262
|
}
|
|
240
263
|
function removeRoomType(roomName) {
|
|
241
264
|
delete handlers[roomName];
|
|
242
|
-
if (!import_DevMode.isDevMode) {
|
|
243
|
-
cleanupStaleRooms(roomName);
|
|
244
|
-
}
|
|
245
265
|
}
|
|
246
266
|
function hasHandler(roomName) {
|
|
247
267
|
import_Logger.logger.warn("hasHandler() is deprecated. Use getHandler() instead.");
|
|
@@ -276,7 +296,9 @@ async function createRoom(roomName, clientOptions) {
|
|
|
276
296
|
} catch (e) {
|
|
277
297
|
if (e.message === "ipc_timeout") {
|
|
278
298
|
(0, import_Debug.debugAndPrintError)(`${e.message}: create room request timed out for ${roomName} on processId ${selectedProcessId}.`);
|
|
279
|
-
|
|
299
|
+
if (enableHealthChecks) {
|
|
300
|
+
await stats.excludeProcess(selectedProcessId);
|
|
301
|
+
}
|
|
280
302
|
room = await handleCreateRoom(roomName, clientOptions);
|
|
281
303
|
} else {
|
|
282
304
|
throw e;
|
|
@@ -300,9 +322,7 @@ async function handleCreateRoom(roomName, clientOptions, restoringRoomId) {
|
|
|
300
322
|
} else {
|
|
301
323
|
room.roomId = (0, import_Utils.generateId)();
|
|
302
324
|
}
|
|
303
|
-
|
|
304
|
-
room.setState(room.state);
|
|
305
|
-
}
|
|
325
|
+
room["__init"]();
|
|
306
326
|
room.roomName = roomName;
|
|
307
327
|
room.presence = presence;
|
|
308
328
|
const additionalListingData = handler.getFilterOptions(clientOptions);
|
|
@@ -342,13 +362,21 @@ async function handleCreateRoom(roomName, clientOptions, restoringRoomId) {
|
|
|
342
362
|
room._events.removeAllListeners("unlock");
|
|
343
363
|
room._events.removeAllListeners("visibility-change");
|
|
344
364
|
room._events.removeAllListeners("dispose");
|
|
365
|
+
if (stats.local.roomCount <= 0) {
|
|
366
|
+
events.emit("no-active-rooms");
|
|
367
|
+
}
|
|
345
368
|
});
|
|
346
369
|
await createRoomReferences(room, true);
|
|
347
|
-
|
|
370
|
+
if (state !== 2 /* SHUTTING_DOWN */) {
|
|
371
|
+
await room.listing.save();
|
|
372
|
+
}
|
|
348
373
|
handler.emit("create", room);
|
|
349
374
|
return room.listing;
|
|
350
375
|
}
|
|
351
376
|
function getRoomById(roomId) {
|
|
377
|
+
return driver.findOne({ roomId });
|
|
378
|
+
}
|
|
379
|
+
function getLocalRoomById(roomId) {
|
|
352
380
|
return rooms[roomId];
|
|
353
381
|
}
|
|
354
382
|
function disconnectAll(closeCode) {
|
|
@@ -357,24 +385,42 @@ function disconnectAll(closeCode) {
|
|
|
357
385
|
if (!rooms.hasOwnProperty(roomId)) {
|
|
358
386
|
continue;
|
|
359
387
|
}
|
|
360
|
-
|
|
361
|
-
room._events.removeAllListeners("leave");
|
|
362
|
-
promises.push(room.disconnect(closeCode));
|
|
388
|
+
promises.push(rooms[roomId].disconnect(closeCode));
|
|
363
389
|
}
|
|
364
390
|
return promises;
|
|
365
391
|
}
|
|
392
|
+
async function lockAndDisposeAll() {
|
|
393
|
+
await stats.excludeProcess(processId);
|
|
394
|
+
if (enableHealthChecks) {
|
|
395
|
+
stats.clearAutoPersistInterval();
|
|
396
|
+
}
|
|
397
|
+
const noActiveRooms = new import_Utils.Deferred();
|
|
398
|
+
if (stats.local.roomCount <= 0) {
|
|
399
|
+
noActiveRooms.resolve();
|
|
400
|
+
} else {
|
|
401
|
+
events.once("no-active-rooms", () => noActiveRooms.resolve());
|
|
402
|
+
}
|
|
403
|
+
for (const roomId in rooms) {
|
|
404
|
+
if (!rooms.hasOwnProperty(roomId)) {
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
const room = rooms[roomId];
|
|
408
|
+
room.lock();
|
|
409
|
+
room.onBeforeShutdown();
|
|
410
|
+
}
|
|
411
|
+
await noActiveRooms;
|
|
412
|
+
}
|
|
366
413
|
async function gracefullyShutdown() {
|
|
367
|
-
if (
|
|
414
|
+
if (state === 2 /* SHUTTING_DOWN */) {
|
|
368
415
|
return Promise.reject("already_shutting_down");
|
|
369
416
|
}
|
|
370
|
-
|
|
417
|
+
(0, import_Debug.debugMatchMaking)(`${processId} is shutting down!`);
|
|
371
418
|
state = 2 /* SHUTTING_DOWN */;
|
|
372
419
|
onReady = void 0;
|
|
373
|
-
|
|
420
|
+
await lockAndDisposeAll();
|
|
374
421
|
if (import_DevMode.isDevMode) {
|
|
375
422
|
await (0, import_DevMode.cacheRoomHistory)(rooms);
|
|
376
423
|
}
|
|
377
|
-
await stats.excludeProcess(processId);
|
|
378
424
|
await removeRoomsByProcessId(processId);
|
|
379
425
|
presence.unsubscribe(getProcessChannel());
|
|
380
426
|
return Promise.all(disconnectAll(
|
|
@@ -399,7 +445,7 @@ async function reserveSeatFor(room, options, authData) {
|
|
|
399
445
|
);
|
|
400
446
|
} catch (e) {
|
|
401
447
|
(0, import_Debug.debugMatchMaking)(e);
|
|
402
|
-
if (e.message === "ipc_timeout" && !await healthCheckProcessId(room.processId)) {
|
|
448
|
+
if (e.message === "ipc_timeout" && !(enableHealthChecks && await healthCheckProcessId(room.processId))) {
|
|
403
449
|
throw new import_SeatReservationError.SeatReservationError(`process ${room.processId} is not available.`);
|
|
404
450
|
} else {
|
|
405
451
|
successfulSeatReservation = false;
|
|
@@ -414,12 +460,9 @@ async function reserveSeatFor(room, options, authData) {
|
|
|
414
460
|
}
|
|
415
461
|
return response;
|
|
416
462
|
}
|
|
417
|
-
function callOnAuth(roomName,
|
|
463
|
+
function callOnAuth(roomName, clientOptions, authContext) {
|
|
418
464
|
const roomClass = getRoomClass(roomName);
|
|
419
|
-
return roomClass && roomClass["onAuth"] && roomClass["onAuth"] !== import_Room.Room["onAuth"] ? roomClass["onAuth"](
|
|
420
|
-
}
|
|
421
|
-
async function cleanupStaleRooms(roomName) {
|
|
422
|
-
await presence.del(getHandlerConcurrencyKey(roomName));
|
|
465
|
+
return roomClass && roomClass["onAuth"] && roomClass["onAuth"] !== import_Room.Room["onAuth"] ? roomClass["onAuth"](authContext.token, clientOptions, authContext) : void 0;
|
|
423
466
|
}
|
|
424
467
|
async function healthCheckAllProcesses() {
|
|
425
468
|
const allStats = await stats.fetchAll();
|
|
@@ -461,13 +504,7 @@ function healthCheckProcessId(processId2) {
|
|
|
461
504
|
return _healthCheckByProcessId[processId2];
|
|
462
505
|
}
|
|
463
506
|
async function removeRoomsByProcessId(processId2) {
|
|
464
|
-
|
|
465
|
-
await driver.cleanup(processId2);
|
|
466
|
-
} else {
|
|
467
|
-
const cachedRooms = await driver.find({ processId: processId2 }, { _id: 1 });
|
|
468
|
-
import_Logger.logger.debug("> Removing stale rooms by processId:", processId2, `(${cachedRooms.length} rooms found)`);
|
|
469
|
-
cachedRooms.forEach((room) => room.remove());
|
|
470
|
-
}
|
|
507
|
+
await driver.cleanup(processId2);
|
|
471
508
|
}
|
|
472
509
|
async function createRoomReferences(room, init = false) {
|
|
473
510
|
rooms[room.roomId] = room;
|
|
@@ -483,29 +520,42 @@ async function createRoomReferences(room, init = false) {
|
|
|
483
520
|
}
|
|
484
521
|
return true;
|
|
485
522
|
}
|
|
486
|
-
async function
|
|
523
|
+
async function concurrentJoinOrCreateRoomLock(handler, concurrencyKey, callback) {
|
|
487
524
|
return new Promise(async (resolve, reject) => {
|
|
488
|
-
const
|
|
489
|
-
const concurrency = await presence.
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
}
|
|
499
|
-
setTimeout(async () => {
|
|
525
|
+
const hkey = getConcurrencyHashKey(handler.name);
|
|
526
|
+
const concurrency = await presence.hincrbyex(
|
|
527
|
+
hkey,
|
|
528
|
+
concurrencyKey,
|
|
529
|
+
1,
|
|
530
|
+
// increment by 1
|
|
531
|
+
import_Utils.MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME * 2
|
|
532
|
+
// expire in 2x the time of MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME
|
|
533
|
+
) - 1;
|
|
534
|
+
const fulfill = async (roomId) => {
|
|
500
535
|
try {
|
|
501
|
-
|
|
502
|
-
resolve(result);
|
|
536
|
+
resolve(await callback(roomId));
|
|
503
537
|
} catch (e) {
|
|
504
538
|
reject(e);
|
|
505
539
|
} finally {
|
|
506
|
-
await presence.
|
|
540
|
+
await presence.hincrby(hkey, concurrencyKey, -1);
|
|
507
541
|
}
|
|
508
|
-
}
|
|
542
|
+
};
|
|
543
|
+
if (concurrency > 0) {
|
|
544
|
+
(0, import_Debug.debugMatchMaking)(
|
|
545
|
+
"receiving %d concurrent joinOrCreate for '%s' (%s)",
|
|
546
|
+
concurrency,
|
|
547
|
+
handler.name,
|
|
548
|
+
concurrencyKey
|
|
549
|
+
);
|
|
550
|
+
const result = await presence.brpop(
|
|
551
|
+
`l:${handler.name}:${concurrencyKey}`,
|
|
552
|
+
import_Utils.MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME + Math.min(concurrency, 3) * 0.2
|
|
553
|
+
// add extra milliseconds for each concurrent request
|
|
554
|
+
);
|
|
555
|
+
return await fulfill(result && result[1]);
|
|
556
|
+
} else {
|
|
557
|
+
return await fulfill();
|
|
558
|
+
}
|
|
509
559
|
});
|
|
510
560
|
}
|
|
511
561
|
function onClientJoinRoom(room, client) {
|
|
@@ -530,24 +580,24 @@ function onVisibilityChange(room, isInvisible) {
|
|
|
530
580
|
handlers[room.roomName].emit("visibility-change", room, isInvisible);
|
|
531
581
|
}
|
|
532
582
|
async function disposeRoom(roomName, room) {
|
|
533
|
-
(0, import_Debug.debugMatchMaking)("disposing '%s' (%s) on processId '%s' (graceful shutdown: %s)", roomName, room.roomId, processId,
|
|
534
|
-
|
|
535
|
-
|
|
583
|
+
(0, import_Debug.debugMatchMaking)("disposing '%s' (%s) on processId '%s' (graceful shutdown: %s)", roomName, room.roomId, processId, state === 2 /* SHUTTING_DOWN */);
|
|
584
|
+
room.listing.remove();
|
|
585
|
+
stats.local.roomCount--;
|
|
586
|
+
if (state !== 2 /* SHUTTING_DOWN */) {
|
|
536
587
|
stats.persist();
|
|
537
588
|
if (import_DevMode.isDevMode) {
|
|
538
589
|
await presence.hdel((0, import_DevMode.getRoomRestoreListKey)(), room.roomId);
|
|
539
590
|
}
|
|
540
591
|
}
|
|
541
592
|
handlers[roomName].emit("dispose", room);
|
|
542
|
-
presence.del(getHandlerConcurrencyKey(roomName));
|
|
543
593
|
presence.unsubscribe(getRoomChannel(room.roomId));
|
|
544
594
|
delete rooms[room.roomId];
|
|
545
595
|
}
|
|
546
596
|
function getRoomChannel(roomId) {
|
|
547
597
|
return `$${roomId}`;
|
|
548
598
|
}
|
|
549
|
-
function
|
|
550
|
-
return `
|
|
599
|
+
function getConcurrencyHashKey(roomName) {
|
|
600
|
+
return `ch:${roomName}`;
|
|
551
601
|
}
|
|
552
602
|
function getProcessChannel(id = processId) {
|
|
553
603
|
return `p:${id}`;
|
|
@@ -556,7 +606,6 @@ function getProcessChannel(id = processId) {
|
|
|
556
606
|
0 && (module.exports = {
|
|
557
607
|
MatchMakerState,
|
|
558
608
|
accept,
|
|
559
|
-
cleanupStaleRooms,
|
|
560
609
|
controller,
|
|
561
610
|
create,
|
|
562
611
|
createRoom,
|
|
@@ -565,6 +614,7 @@ function getProcessChannel(id = processId) {
|
|
|
565
614
|
driver,
|
|
566
615
|
findOneRoomAvailable,
|
|
567
616
|
getHandler,
|
|
617
|
+
getLocalRoomById,
|
|
568
618
|
getRoomById,
|
|
569
619
|
getRoomClass,
|
|
570
620
|
gracefullyShutdown,
|
|
@@ -572,7 +622,6 @@ function getProcessChannel(id = processId) {
|
|
|
572
622
|
hasHandler,
|
|
573
623
|
healthCheckAllProcesses,
|
|
574
624
|
healthCheckProcessId,
|
|
575
|
-
isGracefullyShuttingDown,
|
|
576
625
|
join,
|
|
577
626
|
joinById,
|
|
578
627
|
joinOrCreate,
|
|
@@ -586,6 +635,7 @@ function getProcessChannel(id = processId) {
|
|
|
586
635
|
removeRoomType,
|
|
587
636
|
reserveSeatFor,
|
|
588
637
|
selectProcessIdToCreateRoom,
|
|
638
|
+
setHealthChecksEnabled,
|
|
589
639
|
setup,
|
|
590
640
|
state,
|
|
591
641
|
stats
|