@resolveio/server-lib 20.14.33 → 20.14.34
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/package.json
CHANGED
package/server-app.d.ts
CHANGED
|
@@ -29,6 +29,13 @@ export declare class ResolveIOMainServer {
|
|
|
29
29
|
private _workerServerManager;
|
|
30
30
|
private _httpServerClosePromise;
|
|
31
31
|
private _websocketServerClosePromise;
|
|
32
|
+
private _wsConnectDebug;
|
|
33
|
+
private _perfDebug;
|
|
34
|
+
private _perfDebugIntervalMs;
|
|
35
|
+
private _perfDebugTimer;
|
|
36
|
+
private _perfDebugLastCpu;
|
|
37
|
+
private _perfDebugLastTs;
|
|
38
|
+
private _eventLoopHistogram;
|
|
32
39
|
private _serverStartTime;
|
|
33
40
|
private _lastErrorMsg;
|
|
34
41
|
private _debugMsgRecv;
|
|
@@ -68,6 +75,12 @@ export declare class ResolveIOMainServer {
|
|
|
68
75
|
private decodeBufferPayload;
|
|
69
76
|
private parseTextFallback;
|
|
70
77
|
private looksLikeTextPayload;
|
|
78
|
+
private resolveConnectDebug;
|
|
79
|
+
private resolvePerfDebug;
|
|
80
|
+
private parsePositiveInt;
|
|
81
|
+
private startPerfDebug;
|
|
82
|
+
private parseDebugFlag;
|
|
83
|
+
private logConnectDebug;
|
|
71
84
|
private triggerClientHeartbeat;
|
|
72
85
|
private shouldDeferHeartbeat;
|
|
73
86
|
private handleClientMessage;
|
package/server-app.js
CHANGED
|
@@ -79,6 +79,7 @@ var http_1 = require("http");
|
|
|
79
79
|
var jwt = require("jsonwebtoken");
|
|
80
80
|
var moment = require("moment-timezone");
|
|
81
81
|
var msgpackr_1 = require("msgpackr");
|
|
82
|
+
var perf_hooks_1 = require("perf_hooks");
|
|
82
83
|
var url_1 = require("url");
|
|
83
84
|
var WebSocket = require("ws");
|
|
84
85
|
var log_collection_1 = require("./collections/log.collection");
|
|
@@ -109,6 +110,13 @@ var ResolveIOMainServer = /** @class */ (function () {
|
|
|
109
110
|
this._clientRoutes = [];
|
|
110
111
|
this._httpServerClosePromise = null;
|
|
111
112
|
this._websocketServerClosePromise = null;
|
|
113
|
+
this._wsConnectDebug = false;
|
|
114
|
+
this._perfDebug = false;
|
|
115
|
+
this._perfDebugIntervalMs = 2000;
|
|
116
|
+
this._perfDebugTimer = null;
|
|
117
|
+
this._perfDebugLastCpu = null;
|
|
118
|
+
this._perfDebugLastTs = 0;
|
|
119
|
+
this._eventLoopHistogram = null;
|
|
112
120
|
this._lastErrorMsg = null;
|
|
113
121
|
this._debugMsgRecv = 0;
|
|
114
122
|
this._debugMsgQueue = 0;
|
|
@@ -143,11 +151,14 @@ var ResolveIOMainServer = /** @class */ (function () {
|
|
|
143
151
|
case 0:
|
|
144
152
|
this._serverStartTime = new Date();
|
|
145
153
|
this._lastErrorMsg = null;
|
|
154
|
+
this._wsConnectDebug = this.resolveConnectDebug();
|
|
155
|
+
this._perfDebug = this.resolvePerfDebug();
|
|
146
156
|
_a = this;
|
|
147
157
|
return [4 /*yield*/, monitor_manager_1.MonitorManager.create()];
|
|
148
158
|
case 1:
|
|
149
159
|
_a._monitorManager = _b.sent();
|
|
150
160
|
this._monitorManagerFunction = new monitor_manager_1.MonitorManagerFunction();
|
|
161
|
+
this.startPerfDebug();
|
|
151
162
|
// Check for workers and decide what to start
|
|
152
163
|
this._isWorkersEnabled = process.env.IS_WORKERS_ENABLED === 'true';
|
|
153
164
|
this._isWorkerInstance = process.env.IS_WORKER_INSTANCE === 'true';
|
|
@@ -762,8 +773,9 @@ var ResolveIOMainServer = /** @class */ (function () {
|
|
|
762
773
|
this._serverWSS.on('connection', function (ws, req) { return __awaiter(_this, void 0, void 0, function () {
|
|
763
774
|
var workerId_1, workerIndex, workerInstance, rootUrl, requestUrl, workerIndexForLog, workerInstanceForLog, interval_1, lastComm_1, missedPongs_1, heartbeatIntervalMs, maxMissedPongs_1, maxSilenceMs_1;
|
|
764
775
|
var _this = this;
|
|
765
|
-
|
|
766
|
-
|
|
776
|
+
var _a, _b;
|
|
777
|
+
return __generator(this, function (_c) {
|
|
778
|
+
switch (_c.label) {
|
|
767
779
|
case 0:
|
|
768
780
|
if (!(req.url && req.url.includes('workerToken='))) return [3 /*break*/, 1];
|
|
769
781
|
workerId_1 = (0, common_1.objectIdHexString)();
|
|
@@ -778,7 +790,7 @@ var ResolveIOMainServer = /** @class */ (function () {
|
|
|
778
790
|
workerIndex = requestUrl.searchParams.get('workerIndex');
|
|
779
791
|
workerInstance = requestUrl.searchParams.get('workerInstance');
|
|
780
792
|
}
|
|
781
|
-
catch (
|
|
793
|
+
catch (_d) {
|
|
782
794
|
workerIndex = null;
|
|
783
795
|
workerInstance = null;
|
|
784
796
|
}
|
|
@@ -885,9 +897,17 @@ var ResolveIOMainServer = /** @class */ (function () {
|
|
|
885
897
|
ws['user_readonly'] = req['user_readonly'];
|
|
886
898
|
ws['doc_user'] = req['doc_user'];
|
|
887
899
|
this._websocketManager.addWebSocket(ws);
|
|
900
|
+
this.logConnectDebug('WS client connected', {
|
|
901
|
+
id_socket: ws['id_socket'],
|
|
902
|
+
id_user: ws['id_user'],
|
|
903
|
+
user: ws['user'],
|
|
904
|
+
url: req === null || req === void 0 ? void 0 : req.url,
|
|
905
|
+
ip: (_a = req === null || req === void 0 ? void 0 : req.socket) === null || _a === void 0 ? void 0 : _a.remoteAddress,
|
|
906
|
+
origin: (_b = req === null || req === void 0 ? void 0 : req.headers) === null || _b === void 0 ? void 0 : _b.origin
|
|
907
|
+
});
|
|
888
908
|
return [4 /*yield*/, this._subscriptionManager.createLoggedInUser(ws['id_socket'])];
|
|
889
909
|
case 2:
|
|
890
|
-
|
|
910
|
+
_c.sent();
|
|
891
911
|
setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
892
912
|
return __generator(this, function (_a) {
|
|
893
913
|
switch (_a.label) {
|
|
@@ -994,14 +1014,20 @@ var ResolveIOMainServer = /** @class */ (function () {
|
|
|
994
1014
|
.on('close', function () { return __awaiter(_this, void 0, void 0, function () {
|
|
995
1015
|
return __generator(this, function (_a) {
|
|
996
1016
|
switch (_a.label) {
|
|
997
|
-
case 0:
|
|
1017
|
+
case 0:
|
|
1018
|
+
this.logConnectDebug('WS client closed', {
|
|
1019
|
+
id_socket: ws['id_socket'],
|
|
1020
|
+
id_user: ws['id_user'],
|
|
1021
|
+
user: ws['user']
|
|
1022
|
+
});
|
|
1023
|
+
return [4 /*yield*/, this.unsubscribeWS(ws)];
|
|
998
1024
|
case 1:
|
|
999
1025
|
_a.sent();
|
|
1000
1026
|
return [2 /*return*/];
|
|
1001
1027
|
}
|
|
1002
1028
|
});
|
|
1003
1029
|
}); });
|
|
1004
|
-
|
|
1030
|
+
_c.label = 3;
|
|
1005
1031
|
case 3: return [2 /*return*/];
|
|
1006
1032
|
}
|
|
1007
1033
|
});
|
|
@@ -1087,6 +1113,11 @@ var ResolveIOMainServer = /** @class */ (function () {
|
|
|
1087
1113
|
// If the top level is not an array, let's skip
|
|
1088
1114
|
if (!Array.isArray(socketData[0])) {
|
|
1089
1115
|
console.log('Invalid message format (expected array of arrays)', socketData);
|
|
1116
|
+
this.logConnectDebug('Invalid message format', {
|
|
1117
|
+
id_socket: ws ? ws['id_socket'] : null,
|
|
1118
|
+
user: ws ? ws['user'] : null,
|
|
1119
|
+
preview: Array.isArray(socketData) ? socketData.slice(0, 3) : socketData
|
|
1120
|
+
});
|
|
1090
1121
|
return [2 /*return*/];
|
|
1091
1122
|
}
|
|
1092
1123
|
_b.label = 1;
|
|
@@ -1164,6 +1195,103 @@ var ResolveIOMainServer = /** @class */ (function () {
|
|
|
1164
1195
|
var first = trimmed[0];
|
|
1165
1196
|
return first === '[' || first === '{' || first === '"' || first === 'p' || first === 'P';
|
|
1166
1197
|
};
|
|
1198
|
+
ResolveIOMainServer.prototype.resolveConnectDebug = function () {
|
|
1199
|
+
var _a, _b, _c;
|
|
1200
|
+
var config = resolveio_server_app_1.ResolveIOServer.getServerConfig ? resolveio_server_app_1.ResolveIOServer.getServerConfig() : null;
|
|
1201
|
+
var raw = (_c = (_b = (_a = process.env.WS_CONNECT_DEBUG) !== null && _a !== void 0 ? _a : process.env.CONNECT_DEBUG) !== null && _b !== void 0 ? _b : config === null || config === void 0 ? void 0 : config['WS_CONNECT_DEBUG']) !== null && _c !== void 0 ? _c : config === null || config === void 0 ? void 0 : config['CONNECT_DEBUG'];
|
|
1202
|
+
return this.parseDebugFlag(raw);
|
|
1203
|
+
};
|
|
1204
|
+
ResolveIOMainServer.prototype.resolvePerfDebug = function () {
|
|
1205
|
+
var _a, _b, _c;
|
|
1206
|
+
var config = resolveio_server_app_1.ResolveIOServer.getServerConfig ? resolveio_server_app_1.ResolveIOServer.getServerConfig() : null;
|
|
1207
|
+
var raw = (_c = (_b = (_a = process.env.PERF_DEBUG) !== null && _a !== void 0 ? _a : process.env.CPU_DEBUG) !== null && _b !== void 0 ? _b : config === null || config === void 0 ? void 0 : config['PERF_DEBUG']) !== null && _c !== void 0 ? _c : config === null || config === void 0 ? void 0 : config['CPU_DEBUG'];
|
|
1208
|
+
return this.parseDebugFlag(raw);
|
|
1209
|
+
};
|
|
1210
|
+
ResolveIOMainServer.prototype.parsePositiveInt = function (value, fallback) {
|
|
1211
|
+
var parsed = parseInt(value !== null && value !== void 0 ? value : '', 10);
|
|
1212
|
+
if (Number.isNaN(parsed) || parsed <= 0) {
|
|
1213
|
+
return fallback;
|
|
1214
|
+
}
|
|
1215
|
+
return parsed;
|
|
1216
|
+
};
|
|
1217
|
+
ResolveIOMainServer.prototype.startPerfDebug = function () {
|
|
1218
|
+
var _this = this;
|
|
1219
|
+
var _a;
|
|
1220
|
+
if (!this._perfDebug || this._perfDebugTimer) {
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
this._perfDebugIntervalMs = this.parsePositiveInt((_a = process.env.PERF_DEBUG_INTERVAL_MS) !== null && _a !== void 0 ? _a : process.env.CPU_DEBUG_INTERVAL_MS, this._perfDebugIntervalMs);
|
|
1224
|
+
this._perfDebugLastCpu = process.cpuUsage();
|
|
1225
|
+
this._perfDebugLastTs = Date.now();
|
|
1226
|
+
this._eventLoopHistogram = (0, perf_hooks_1.monitorEventLoopDelay)({ resolution: 20 });
|
|
1227
|
+
this._eventLoopHistogram.enable();
|
|
1228
|
+
this._perfDebugTimer = setInterval(function () {
|
|
1229
|
+
var now = Date.now();
|
|
1230
|
+
var elapsedMs = now - _this._perfDebugLastTs;
|
|
1231
|
+
var cpuDiff = _this._perfDebugLastCpu ? process.cpuUsage(_this._perfDebugLastCpu) : process.cpuUsage();
|
|
1232
|
+
var cpuMs = (cpuDiff.user + cpuDiff.system) / 1000;
|
|
1233
|
+
var cpuPct = elapsedMs > 0 ? (cpuMs / elapsedMs) * 100 : 0;
|
|
1234
|
+
var mem = process.memoryUsage();
|
|
1235
|
+
var heapUsedMb = (0, common_1.round)((mem.heapUsed / 1024 / 1024) * 10) / 10;
|
|
1236
|
+
var rssMb = (0, common_1.round)((mem.rss / 1024 / 1024) * 10) / 10;
|
|
1237
|
+
var handles = typeof process._getActiveHandles === 'function'
|
|
1238
|
+
? process._getActiveHandles().length
|
|
1239
|
+
: null;
|
|
1240
|
+
var requests = typeof process._getActiveRequests === 'function'
|
|
1241
|
+
? process._getActiveRequests().length
|
|
1242
|
+
: null;
|
|
1243
|
+
var histogram = _this._eventLoopHistogram;
|
|
1244
|
+
var eventLoop = histogram ? {
|
|
1245
|
+
meanMs: (0, common_1.round)((histogram.mean / 1e6) * 100) / 100,
|
|
1246
|
+
p50Ms: (0, common_1.round)((histogram.percentile(50) / 1e6) * 100) / 100,
|
|
1247
|
+
p95Ms: (0, common_1.round)((histogram.percentile(95) / 1e6) * 100) / 100,
|
|
1248
|
+
p99Ms: (0, common_1.round)((histogram.percentile(99) / 1e6) * 100) / 100,
|
|
1249
|
+
maxMs: (0, common_1.round)((histogram.max / 1e6) * 100) / 100
|
|
1250
|
+
} : null;
|
|
1251
|
+
histogram === null || histogram === void 0 ? void 0 : histogram.reset();
|
|
1252
|
+
console.log(new Date(), '[Perf Debug]', JSON.stringify({
|
|
1253
|
+
cpuPct: (0, common_1.round)(cpuPct * 10) / 10,
|
|
1254
|
+
cpuMs: (0, common_1.round)(cpuMs),
|
|
1255
|
+
elapsedMs: elapsedMs,
|
|
1256
|
+
eventLoop: eventLoop,
|
|
1257
|
+
heapUsedMb: heapUsedMb,
|
|
1258
|
+
rssMb: rssMb,
|
|
1259
|
+
activeHandles: handles,
|
|
1260
|
+
activeRequests: requests,
|
|
1261
|
+
msgRecv: _this._debugMsgRecv,
|
|
1262
|
+
msgQueue: _this._debugMsgQueue
|
|
1263
|
+
}));
|
|
1264
|
+
_this._perfDebugLastCpu = process.cpuUsage();
|
|
1265
|
+
_this._perfDebugLastTs = now;
|
|
1266
|
+
}, this._perfDebugIntervalMs);
|
|
1267
|
+
};
|
|
1268
|
+
ResolveIOMainServer.prototype.parseDebugFlag = function (value) {
|
|
1269
|
+
if (value === true) {
|
|
1270
|
+
return true;
|
|
1271
|
+
}
|
|
1272
|
+
if (value === false || value === null || value === undefined) {
|
|
1273
|
+
return false;
|
|
1274
|
+
}
|
|
1275
|
+
if (typeof value === 'number') {
|
|
1276
|
+
return value === 1;
|
|
1277
|
+
}
|
|
1278
|
+
if (typeof value === 'string') {
|
|
1279
|
+
var normalized = value.trim().toLowerCase();
|
|
1280
|
+
return ['1', 'true', 'yes', 'y', 'on'].includes(normalized);
|
|
1281
|
+
}
|
|
1282
|
+
return false;
|
|
1283
|
+
};
|
|
1284
|
+
ResolveIOMainServer.prototype.logConnectDebug = function (message, details) {
|
|
1285
|
+
if (!this._wsConnectDebug) {
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
if (details) {
|
|
1289
|
+
console.log(new Date(), '[Connect Debug]', message, JSON.stringify(details));
|
|
1290
|
+
}
|
|
1291
|
+
else {
|
|
1292
|
+
console.log(new Date(), '[Connect Debug]', message);
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1167
1295
|
ResolveIOMainServer.prototype.triggerClientHeartbeat = function (ws) {
|
|
1168
1296
|
return __awaiter(this, void 0, void 0, function () {
|
|
1169
1297
|
var err_1;
|
|
@@ -1240,6 +1368,15 @@ var ResolveIOMainServer = /** @class */ (function () {
|
|
|
1240
1368
|
if (!(type === 'subscription')) return [3 /*break*/, 4];
|
|
1241
1369
|
subType = msg[4];
|
|
1242
1370
|
pub = msg[5];
|
|
1371
|
+
this.logConnectDebug('Subscription message', {
|
|
1372
|
+
subType: subType,
|
|
1373
|
+
publication: pub,
|
|
1374
|
+
messageId: messageId,
|
|
1375
|
+
messageRoute: messageRoute_1,
|
|
1376
|
+
args: Math.max(0, msg.length - 6),
|
|
1377
|
+
id_socket: ws ? ws['id_socket'] : null,
|
|
1378
|
+
user: ws ? ws['user'] : null
|
|
1379
|
+
});
|
|
1243
1380
|
if (!(subType === 'sub')) return [3 /*break*/, 2];
|
|
1244
1381
|
return [4 /*yield*/, this._subscriptionManager.subscribe(messageRoute_1, messageDate, ws, messageId, pub, msg.slice(6))];
|
|
1245
1382
|
case 1:
|
|
@@ -1533,6 +1670,11 @@ var ResolveIOMainServer = /** @class */ (function () {
|
|
|
1533
1670
|
if (this._subscriptionManager && this._methodManager.getEnableDebug()) {
|
|
1534
1671
|
console.log(new Date(), 'Server App', 'Unsub WS', ws['user'], ws['id_socket']);
|
|
1535
1672
|
}
|
|
1673
|
+
this.logConnectDebug('WS unsubscribe', {
|
|
1674
|
+
id_socket: ws ? ws['id_socket'] : null,
|
|
1675
|
+
id_user: ws ? ws['id_user'] : null,
|
|
1676
|
+
user: ws ? ws['user'] : null
|
|
1677
|
+
});
|
|
1536
1678
|
return [4 /*yield*/, this._subscriptionManager.unsubscribeAll(ws)];
|
|
1537
1679
|
case 1:
|
|
1538
1680
|
_a.sent();
|