@resolveio/server-lib 20.14.15 → 20.14.17

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/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");
@@ -120,6 +121,8 @@ var ResolveIOMainServer = /** @class */ (function () {
120
121
  this._clientHeartbeatBackpressureBytes = 5 * 1024 * 1024;
121
122
  this._eventLoopLagIntervalMs = 500;
122
123
  this._eventLoopLagThresholdMs = 300;
124
+ this._eventLoopDelayStatsIntervalMs = 10000;
125
+ this._slowHandlerThresholdMs = 200;
123
126
  }
124
127
  ResolveIOMainServer.create = function () {
125
128
  return __awaiter(this, void 0, void 0, function () {
@@ -385,6 +388,45 @@ var ResolveIOMainServer = /** @class */ (function () {
385
388
  ResolveIOMainServer.prototype.startEventLoopLagMonitor = function () {
386
389
  var _this = this;
387
390
  var lastTick = Date.now();
391
+ var delayMonitor = (0, perf_hooks_1.monitorEventLoopDelay)({ resolution: 20 });
392
+ delayMonitor.enable();
393
+ var gcKindLabels = {};
394
+ var perfConstants = perf_hooks_1.performance === null || perf_hooks_1.performance === void 0 ? void 0 : perf_hooks_1.performance.constants;
395
+ if (perfConstants) {
396
+ if (typeof perfConstants.NODE_PERFORMANCE_GC_MAJOR !== 'undefined') {
397
+ gcKindLabels[perfConstants.NODE_PERFORMANCE_GC_MAJOR] = 'major';
398
+ }
399
+ if (typeof perfConstants.NODE_PERFORMANCE_GC_MINOR !== 'undefined') {
400
+ gcKindLabels[perfConstants.NODE_PERFORMANCE_GC_MINOR] = 'minor';
401
+ }
402
+ if (typeof perfConstants.NODE_PERFORMANCE_GC_INCREMENTAL !== 'undefined') {
403
+ gcKindLabels[perfConstants.NODE_PERFORMANCE_GC_INCREMENTAL] = 'incremental';
404
+ }
405
+ if (typeof perfConstants.NODE_PERFORMANCE_GC_WEAKCB !== 'undefined') {
406
+ gcKindLabels[perfConstants.NODE_PERFORMANCE_GC_WEAKCB] = 'weakcb';
407
+ }
408
+ }
409
+ var gcObserver = new perf_hooks_1.PerformanceObserver(function (list) {
410
+ var e_1, _a;
411
+ try {
412
+ for (var _b = __values(list.getEntries()), _c = _b.next(); !_c.done; _c = _b.next()) {
413
+ var entry = _c.value;
414
+ var kindLabel = gcKindLabels[entry.kind] || entry.kind;
415
+ console.log(new Date(), '[GC]', {
416
+ kind: kindLabel,
417
+ durationMs: (0, common_1.round)(entry.duration)
418
+ });
419
+ }
420
+ }
421
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
422
+ finally {
423
+ try {
424
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
425
+ }
426
+ finally { if (e_1) throw e_1.error; }
427
+ }
428
+ });
429
+ gcObserver.observe({ entryTypes: ['gc'] });
388
430
  setInterval(function () {
389
431
  var now = Date.now();
390
432
  var lagMs = now - lastTick - _this._eventLoopLagIntervalMs;
@@ -399,6 +441,19 @@ var ResolveIOMainServer = /** @class */ (function () {
399
441
  });
400
442
  }
401
443
  }, this._eventLoopLagIntervalMs);
444
+ setInterval(function () {
445
+ var p99Ms = (0, common_1.round)(delayMonitor.percentile(99) / 1e6);
446
+ var maxMs = (0, common_1.round)(delayMonitor.max / 1e6);
447
+ var meanMs = (0, common_1.round)(delayMonitor.mean / 1e6);
448
+ if (p99Ms >= _this._eventLoopLagThresholdMs || maxMs >= _this._eventLoopLagThresholdMs) {
449
+ console.log(new Date(), '[Event Loop Delay Stats]', {
450
+ p99Ms: p99Ms,
451
+ maxMs: maxMs,
452
+ meanMs: meanMs
453
+ });
454
+ }
455
+ delayMonitor.reset();
456
+ }, this._eventLoopDelayStatsIntervalMs);
402
457
  };
403
458
  ResolveIOMainServer.prototype.shutdownNetworkServers = function () {
404
459
  return __awaiter(this, void 0, void 0, function () {
@@ -932,7 +987,7 @@ var ResolveIOMainServer = /** @class */ (function () {
932
987
  }
933
988
  });
934
989
  ws.on('message', function (message) { return __awaiter(_this, void 0, void 0, function () {
935
- var socketData, usedBinary, bufferPayload, decodeResult, decodeResult, decodeResult, view, decodeResult, e_1, correlationId, context;
990
+ var socketData, usedBinary, bufferPayload, decodeResult, decodeResult, decodeResult, view, decodeResult, e_2, correlationId, context;
936
991
  return __generator(this, function (_a) {
937
992
  switch (_a.label) {
938
993
  case 0:
@@ -980,15 +1035,15 @@ var ResolveIOMainServer = /** @class */ (function () {
980
1035
  }
981
1036
  return [3 /*break*/, 4];
982
1037
  case 2:
983
- e_1 = _a.sent();
984
- console.log('Error - WS message parse', e_1);
1038
+ e_2 = _a.sent();
1039
+ console.log('Error - WS message parse', e_2);
985
1040
  correlationId = (0, common_1.objectIdHexString)();
986
1041
  context = {
987
1042
  rawBinary: bufferPayload ? bufferPayload.toString('base64') : undefined,
988
1043
  rawMessage: typeof message === 'string' ? message : undefined,
989
- error: e_1 instanceof Error ? { name: e_1.name, message: e_1.message, stack: e_1.stack } : e_1
1044
+ error: e_2 instanceof Error ? { name: e_2.name, message: e_2.message, stack: e_2.stack } : e_2
990
1045
  };
991
- return [4 /*yield*/, this.reportServerError('SERVER - JSON Parse Error - ' + resolveio_server_app_1.ResolveIOServer.getServerConfig()['CLIENT_NAME'], correlationId, context, { context: 'websocket-message-parse' }, 'error', e_1 instanceof Error ? e_1.stack : undefined)];
1046
+ return [4 /*yield*/, this.reportServerError('SERVER - JSON Parse Error - ' + resolveio_server_app_1.ResolveIOServer.getServerConfig()['CLIENT_NAME'], correlationId, context, { context: 'websocket-message-parse' }, 'error', e_2 instanceof Error ? e_2.stack : undefined)];
992
1047
  case 3:
993
1048
  _a.sent();
994
1049
  return [2 /*return*/];
@@ -1028,8 +1083,8 @@ var ResolveIOMainServer = /** @class */ (function () {
1028
1083
  }); });
1029
1084
  // Keep alive timer
1030
1085
  setInterval(function () { return __awaiter(_this, void 0, void 0, function () {
1031
- var _a, _b, ws, e_2_1;
1032
- var e_2, _c;
1086
+ var _a, _b, ws, e_3_1;
1087
+ var e_3, _c;
1033
1088
  return __generator(this, function (_d) {
1034
1089
  switch (_d.label) {
1035
1090
  case 0:
@@ -1070,14 +1125,14 @@ var ResolveIOMainServer = /** @class */ (function () {
1070
1125
  return [3 /*break*/, 1];
1071
1126
  case 9: return [3 /*break*/, 12];
1072
1127
  case 10:
1073
- e_2_1 = _d.sent();
1074
- e_2 = { error: e_2_1 };
1128
+ e_3_1 = _d.sent();
1129
+ e_3 = { error: e_3_1 };
1075
1130
  return [3 /*break*/, 12];
1076
1131
  case 11:
1077
1132
  try {
1078
1133
  if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
1079
1134
  }
1080
- finally { if (e_2) throw e_2.error; }
1135
+ finally { if (e_3) throw e_3.error; }
1081
1136
  return [7 /*endfinally*/];
1082
1137
  case 12: return [2 /*return*/];
1083
1138
  }
@@ -1086,8 +1141,8 @@ var ResolveIOMainServer = /** @class */ (function () {
1086
1141
  };
1087
1142
  ResolveIOMainServer.prototype.processSocketMessage = function (ws, socketData) {
1088
1143
  return __awaiter(this, void 0, void 0, function () {
1089
- var socketData_1, socketData_1_1, message, e_3_1;
1090
- var e_3, _a;
1144
+ var socketData_1, socketData_1_1, message, e_4_1;
1145
+ var e_4, _a;
1091
1146
  return __generator(this, function (_b) {
1092
1147
  switch (_b.label) {
1093
1148
  case 0:
@@ -1126,14 +1181,14 @@ var ResolveIOMainServer = /** @class */ (function () {
1126
1181
  return [3 /*break*/, 2];
1127
1182
  case 5: return [3 /*break*/, 8];
1128
1183
  case 6:
1129
- e_3_1 = _b.sent();
1130
- e_3 = { error: e_3_1 };
1184
+ e_4_1 = _b.sent();
1185
+ e_4 = { error: e_4_1 };
1131
1186
  return [3 /*break*/, 8];
1132
1187
  case 7:
1133
1188
  try {
1134
1189
  if (socketData_1_1 && !socketData_1_1.done && (_a = socketData_1.return)) _a.call(socketData_1);
1135
1190
  }
1136
- finally { if (e_3) throw e_3.error; }
1191
+ finally { if (e_4) throw e_4.error; }
1137
1192
  return [7 /*endfinally*/];
1138
1193
  case 8: return [2 /*return*/];
1139
1194
  }
@@ -1244,32 +1299,43 @@ var ResolveIOMainServer = /** @class */ (function () {
1244
1299
  };
1245
1300
  ResolveIOMainServer.prototype.handleClientMessage = function (ws, msg) {
1246
1301
  return __awaiter(this, void 0, void 0, function () {
1247
- var messageRoute, messageDate, messageId, type, subType, pub, serverRes, offlineUpdates, i, update, data, updateRoute, updateDate, updateMessageId, updateType, method, serverResMethod, err_2, dataCopy, route, date, msgId, msgType, methodName, ack, method, forceWorker, targetWorkerIndex, hasWorkerForMethod, isExcludedFromWorker, errorRes, shouldDispatchToWorker, errorRes;
1302
+ var startMs, logRoute, logType, logDetail, messageRoute_1, messageDate, messageId, type, subType, pub, serverRes, offlineUpdates, i, update, data, updateRoute, updateDate, updateMessageId, updateType, method, serverResMethod, err_2, dataCopy, route, date, msgId, msgType, methodName, ack, method, forceWorker, targetWorkerIndex, hasWorkerForMethod, isExcludedFromWorker, errorRes, shouldDispatchToWorker, errorRes, durationMs;
1248
1303
  var _a;
1249
1304
  return __generator(this, function (_b) {
1250
1305
  switch (_b.label) {
1251
1306
  case 0:
1252
- messageRoute = msg[0];
1307
+ startMs = Date.now();
1308
+ logRoute = msg && msg[0];
1309
+ logType = null;
1310
+ logDetail = null;
1311
+ _b.label = 1;
1312
+ case 1:
1313
+ _b.trys.push([1, , 25, 26]);
1314
+ messageRoute_1 = msg[0];
1253
1315
  messageDate = msg[1];
1254
1316
  messageId = msg[2];
1255
1317
  type = msg[3];
1256
- if (!this.publicProgram && this._clientRoutes.some(function (a) { return messageRoute.includes(a); }) && !ws['doc_user'].roles.groups.some(function (a) { return a.views.some(function (b) { return messageRoute.includes(b) || b.includes(messageRoute); }); }) && !ws['doc_user'].roles.super_admin) {
1318
+ logRoute = messageRoute_1;
1319
+ logType = type;
1320
+ if (!this.publicProgram && this._clientRoutes.some(function (a) { return messageRoute_1.includes(a); }) && !ws['doc_user'].roles.groups.some(function (a) { return a.views.some(function (b) { return messageRoute_1.includes(b) || b.includes(messageRoute_1); }); }) && !ws['doc_user'].roles.super_admin) {
1257
1321
  return [2 /*return*/];
1258
1322
  }
1259
- if (!(type === 'subscription')) return [3 /*break*/, 4];
1323
+ if (!(type === 'subscription')) return [3 /*break*/, 5];
1260
1324
  subType = msg[4];
1261
1325
  pub = msg[5];
1262
- if (!(subType === 'sub')) return [3 /*break*/, 2];
1263
- return [4 /*yield*/, this._subscriptionManager.subscribe(messageRoute, messageDate, ws, messageId, pub, msg.slice(6))];
1264
- case 1:
1265
- _b.sent();
1266
- return [3 /*break*/, 3];
1326
+ logDetail = "".concat(subType, ":").concat(pub);
1327
+ if (!(subType === 'sub')) return [3 /*break*/, 3];
1328
+ return [4 /*yield*/, this._subscriptionManager.subscribe(messageRoute_1, messageDate, ws, messageId, pub, msg.slice(6))];
1267
1329
  case 2:
1268
- this._subscriptionManager.unsubscribe(messageRoute, messageDate, ws, messageId, pub, msg.slice(6));
1269
- _b.label = 3;
1270
- case 3: return [3 /*break*/, 23];
1271
- case 4:
1272
- if (!(!this.publicProgram && type === 'offline')) return [3 /*break*/, 16];
1330
+ _b.sent();
1331
+ return [3 /*break*/, 4];
1332
+ case 3:
1333
+ this._subscriptionManager.unsubscribe(messageRoute_1, messageDate, ws, messageId, pub, msg.slice(6));
1334
+ _b.label = 4;
1335
+ case 4: return [3 /*break*/, 24];
1336
+ case 5:
1337
+ if (!(!this.publicProgram && type === 'offline')) return [3 /*break*/, 17];
1338
+ logDetail = 'offline';
1273
1339
  serverRes = {
1274
1340
  messageId: messageId,
1275
1341
  hasError: false,
@@ -1280,10 +1346,11 @@ var ResolveIOMainServer = /** @class */ (function () {
1280
1346
  }
1281
1347
  this._offlineUpdates.push(ws);
1282
1348
  offlineUpdates = msg[4];
1349
+ logDetail = "offline:".concat(Array.isArray(offlineUpdates) ? offlineUpdates.length : 0);
1283
1350
  i = 0;
1284
- _b.label = 5;
1285
- case 5:
1286
- if (!(i < offlineUpdates.length)) return [3 /*break*/, 15];
1351
+ _b.label = 6;
1352
+ case 6:
1353
+ if (!(i < offlineUpdates.length)) return [3 /*break*/, 16];
1287
1354
  update = offlineUpdates[i];
1288
1355
  data = update.data;
1289
1356
  updateRoute = data.shift();
@@ -1300,11 +1367,11 @@ var ResolveIOMainServer = /** @class */ (function () {
1300
1367
  this._websocketManager.send(ws, serverResMethod);
1301
1368
  }
1302
1369
  if (method === 'insertDocument' && data[0] === 'driver-gps') {
1303
- return [3 /*break*/, 14];
1370
+ return [3 /*break*/, 15];
1304
1371
  }
1305
- if (!(method !== 'reportBuilderGetResults' && method !== 'reportBuilderGetDistinctValue' && method !== 'reportBuilderBuildTree' && method !== 'generatePDF' && method !== 'getWOOfflineData' && method !== 'countQuery' && method !== 'countWithQuery' && method !== 'countCollectionWithQuery' && method !== 'find' && method !== 'findOne' && method !== 'findWithOptions' && method !== 'getDrivers' && method !== 'processAirdropDistribution' && method !== 'qbHandleResponse')) return [3 /*break*/, 8];
1372
+ if (!(method !== 'reportBuilderGetResults' && method !== 'reportBuilderGetDistinctValue' && method !== 'reportBuilderBuildTree' && method !== 'generatePDF' && method !== 'getWOOfflineData' && method !== 'countQuery' && method !== 'countWithQuery' && method !== 'countCollectionWithQuery' && method !== 'find' && method !== 'findOne' && method !== 'findWithOptions' && method !== 'getDrivers' && method !== 'processAirdropDistribution' && method !== 'qbHandleResponse')) return [3 /*break*/, 9];
1306
1373
  if (!(resolveio_server_app_1.ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'https://resolveio.com'
1307
- && resolveio_server_app_1.ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200')) return [3 /*break*/, 6];
1374
+ && resolveio_server_app_1.ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200')) return [3 /*break*/, 7];
1308
1375
  resolveio_server_app_1.ResolveIOServer.getLocalLogManager().writeLog({
1309
1376
  type: 'log',
1310
1377
  data: {
@@ -1318,12 +1385,12 @@ var ResolveIOMainServer = /** @class */ (function () {
1318
1385
  id_user: ws['id_user'] || '',
1319
1386
  user: ws['user'] || '',
1320
1387
  messageId: messageId,
1321
- route: messageRoute,
1388
+ route: messageRoute_1,
1322
1389
  instance_index: process.env.NODE_APP_INSTANCE || '0'
1323
1390
  }
1324
1391
  });
1325
- return [3 /*break*/, 8];
1326
- case 6: return [4 /*yield*/, log_collection_1.Logs.insertOne({
1392
+ return [3 /*break*/, 9];
1393
+ case 7: return [4 /*yield*/, log_collection_1.Logs.insertOne({
1327
1394
  _id: (0, common_1.objectIdHexString)(),
1328
1395
  type: 'client-request',
1329
1396
  collection: '',
@@ -1333,55 +1400,56 @@ var ResolveIOMainServer = /** @class */ (function () {
1333
1400
  id_user: ws['id_user'] || '',
1334
1401
  user: ws['user'] || '',
1335
1402
  messageId: messageId,
1336
- route: messageRoute,
1403
+ route: messageRoute_1,
1337
1404
  client: 'ResolveIO',
1338
1405
  instance: 'backend.resolveio.com',
1339
1406
  instance_index: process.env.NODE_APP_INSTANCE || '0'
1340
1407
  })];
1341
- case 7:
1342
- _b.sent();
1343
- _b.label = 8;
1344
1408
  case 8:
1345
- if (!this._methodManager._methods[method]) return [3 /*break*/, 13];
1409
+ _b.sent();
1346
1410
  _b.label = 9;
1347
1411
  case 9:
1348
- _b.trys.push([9, 11, , 12]);
1349
- return [4 /*yield*/, (_a = this._methodManager.callMethod).call.apply(_a, __spreadArray([Object.assign({}, this._methodManager, method_manager_1.MethodManager.prototype, { id_user: ws['id_user'], user: ws['user'], id_ws: ws['id_socket'] }), method], __read(data), false))];
1412
+ if (!this._methodManager._methods[method]) return [3 /*break*/, 14];
1413
+ _b.label = 10;
1350
1414
  case 10:
1351
- _b.sent();
1352
- return [3 /*break*/, 12];
1415
+ _b.trys.push([10, 12, , 13]);
1416
+ return [4 /*yield*/, (_a = this._methodManager.callMethod).call.apply(_a, __spreadArray([Object.assign({}, this._methodManager, method_manager_1.MethodManager.prototype, { id_user: ws['id_user'], user: ws['user'], id_ws: ws['id_socket'] }), method], __read(data), false))];
1353
1417
  case 11:
1418
+ _b.sent();
1419
+ return [3 /*break*/, 13];
1420
+ case 12:
1354
1421
  err_2 = _b.sent();
1355
1422
  console.log(new Date(), 'Offline Error', JSON.stringify(err_2, null, 2));
1356
- return [3 /*break*/, 12];
1357
- case 12:
1423
+ return [3 /*break*/, 13];
1424
+ case 13:
1358
1425
  if (method === 'updateDocumentOffline' || method === 'updateDocumentPropsOffline') {
1359
1426
  resolveio_server_app_1.ResolveIOServer.getMongoManager().invalidateQueryCache(data[0]);
1360
1427
  }
1361
- return [3 /*break*/, 14];
1362
- case 13:
1363
- console.log('Offline - Could not find method: ' + method);
1364
- _b.label = 14;
1428
+ return [3 /*break*/, 15];
1365
1429
  case 14:
1366
- i++;
1367
- return [3 /*break*/, 5];
1430
+ console.log('Offline - Could not find method: ' + method);
1431
+ _b.label = 15;
1368
1432
  case 15:
1369
- this._offlineUpdates.splice(this._offlineUpdates.map(function (a) { return a['id_socket']; }).indexOf(ws['id_socket']), 1);
1370
- return [3 /*break*/, 23];
1433
+ i++;
1434
+ return [3 /*break*/, 6];
1371
1435
  case 16:
1436
+ this._offlineUpdates.splice(this._offlineUpdates.map(function (a) { return a['id_socket']; }).indexOf(ws['id_socket']), 1);
1437
+ return [3 /*break*/, 24];
1438
+ case 17:
1372
1439
  dataCopy = __spreadArray([], __read(msg), false);
1373
1440
  route = dataCopy.shift();
1374
1441
  date = dataCopy.shift();
1375
1442
  msgId = dataCopy.shift();
1376
1443
  msgType = dataCopy.shift();
1377
- if (!(msgType === 'method')) return [3 /*break*/, 23];
1444
+ if (!(msgType === 'method')) return [3 /*break*/, 24];
1378
1445
  methodName = dataCopy.shift();
1446
+ logDetail = "method:".concat(methodName);
1379
1447
  if (ws['user_readonly']) {
1380
1448
  return [2 /*return*/];
1381
1449
  }
1382
- if (!(methodName !== 'reportBuilderGetResults' && methodName !== 'reportBuilderGetDistinctValue' && methodName !== 'reportBuilderBuildTree' && methodName !== 'generatePDF' && methodName !== 'getWOOfflineData' && methodName !== 'countQuery' && methodName !== 'countWithQuery' && methodName !== 'countCollectionWithQuery' && methodName !== 'find' && methodName !== 'findOne' && methodName !== 'findWithOptions' && methodName !== 'getDrivers' && methodName !== 'processAirdropDistribution')) return [3 /*break*/, 19];
1450
+ if (!(methodName !== 'reportBuilderGetResults' && methodName !== 'reportBuilderGetDistinctValue' && methodName !== 'reportBuilderBuildTree' && methodName !== 'generatePDF' && methodName !== 'getWOOfflineData' && methodName !== 'countQuery' && methodName !== 'countWithQuery' && methodName !== 'countCollectionWithQuery' && methodName !== 'find' && methodName !== 'findOne' && methodName !== 'findWithOptions' && methodName !== 'getDrivers' && methodName !== 'processAirdropDistribution')) return [3 /*break*/, 20];
1383
1451
  if (!(resolveio_server_app_1.ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'https://resolveio.com'
1384
- && resolveio_server_app_1.ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200')) return [3 /*break*/, 17];
1452
+ && resolveio_server_app_1.ResolveIOServer.getServerConfig()['ROOT_URL'] !== 'http://localhost:4200')) return [3 /*break*/, 18];
1385
1453
  resolveio_server_app_1.ResolveIOServer.getLocalLogManager().writeLog({
1386
1454
  type: 'log',
1387
1455
  data: {
@@ -1395,12 +1463,12 @@ var ResolveIOMainServer = /** @class */ (function () {
1395
1463
  id_user: ws['id_user'] || '',
1396
1464
  user: ws['user'] || '',
1397
1465
  messageId: messageId,
1398
- route: messageRoute,
1466
+ route: messageRoute_1,
1399
1467
  instance_index: process.env.NODE_APP_INSTANCE || '0'
1400
1468
  }
1401
1469
  });
1402
- return [3 /*break*/, 19];
1403
- case 17: return [4 /*yield*/, log_collection_1.Logs.insertOne({
1470
+ return [3 /*break*/, 20];
1471
+ case 18: return [4 /*yield*/, log_collection_1.Logs.insertOne({
1404
1472
  _id: (0, common_1.objectIdHexString)(),
1405
1473
  type: 'client-request',
1406
1474
  collection: '',
@@ -1410,15 +1478,15 @@ var ResolveIOMainServer = /** @class */ (function () {
1410
1478
  id_user: ws['id_user'] || '',
1411
1479
  user: ws['user'] || '',
1412
1480
  messageId: messageId,
1413
- route: messageRoute,
1481
+ route: messageRoute_1,
1414
1482
  client: 'ResolveIO',
1415
1483
  instance: 'backend.resolveio.com',
1416
1484
  instance_index: process.env.NODE_APP_INSTANCE || '0'
1417
1485
  })];
1418
- case 18:
1419
- _b.sent();
1420
- _b.label = 19;
1421
1486
  case 19:
1487
+ _b.sent();
1488
+ _b.label = 20;
1489
+ case 20:
1422
1490
  ack = {
1423
1491
  messageId: msgId,
1424
1492
  hasError: false,
@@ -1465,15 +1533,15 @@ var ResolveIOMainServer = /** @class */ (function () {
1465
1533
  this._workerDispatcherManager &&
1466
1534
  (hasWorkerForMethod || forceWorker) &&
1467
1535
  (forceWorker || !isExcludedFromWorker));
1468
- if (!shouldDispatchToWorker) return [3 /*break*/, 20];
1536
+ if (!shouldDispatchToWorker) return [3 /*break*/, 21];
1469
1537
  this._workerDispatcherManager.sendClientTask(msgId, methodName, dataCopy, {
1470
1538
  id_user: ws['id_user'],
1471
1539
  user: ws['user'],
1472
1540
  id_ws: ws['id_socket']
1473
1541
  });
1474
- return [3 /*break*/, 23];
1475
- case 20:
1476
- if (!(forceWorker && this._isWorkersEnabled)) return [3 /*break*/, 21];
1542
+ return [3 /*break*/, 24];
1543
+ case 21:
1544
+ if (!(forceWorker && this._isWorkersEnabled)) return [3 /*break*/, 22];
1477
1545
  errorRes = {
1478
1546
  messageId: msgId,
1479
1547
  hasError: true,
@@ -1482,15 +1550,30 @@ var ResolveIOMainServer = /** @class */ (function () {
1482
1550
  if (ws && ws.readyState === ws.OPEN) {
1483
1551
  this._websocketManager.send(ws, errorRes);
1484
1552
  }
1485
- return [3 /*break*/, 23];
1486
- case 21:
1553
+ return [3 /*break*/, 24];
1554
+ case 22:
1487
1555
  // No worker available: do method locally
1488
- return [4 /*yield*/, this.callMethodLocally(ws, msgId, methodName, dataCopy)];
1489
- case 22:
1556
+ return [4 /*yield*/, this.callMethodLocally(ws, msgId, methodName, dataCopy, messageRoute_1)];
1557
+ case 23:
1490
1558
  // No worker available: do method locally
1491
1559
  _b.sent();
1492
- _b.label = 23;
1493
- case 23: return [2 /*return*/];
1560
+ _b.label = 24;
1561
+ case 24: return [3 /*break*/, 26];
1562
+ case 25:
1563
+ durationMs = Date.now() - startMs;
1564
+ if (durationMs >= this._slowHandlerThresholdMs) {
1565
+ console.log(new Date(), '[Slow WS Message]', {
1566
+ durationMs: durationMs,
1567
+ route: logRoute,
1568
+ type: logType,
1569
+ detail: logDetail,
1570
+ id_user: ws['id_user'] || null,
1571
+ user: ws['user'] || null,
1572
+ id_ws: ws['id_socket'] || null
1573
+ });
1574
+ }
1575
+ return [7 /*endfinally*/];
1576
+ case 26: return [2 /*return*/];
1494
1577
  }
1495
1578
  });
1496
1579
  });
@@ -1498,9 +1581,9 @@ var ResolveIOMainServer = /** @class */ (function () {
1498
1581
  /**
1499
1582
  * callMethodLocally is your old approach for invoking the method in-process.
1500
1583
  */
1501
- ResolveIOMainServer.prototype.callMethodLocally = function (ws, messageId, method, params) {
1584
+ ResolveIOMainServer.prototype.callMethodLocally = function (ws, messageId, method, params, route) {
1502
1585
  return __awaiter(this, void 0, void 0, function () {
1503
- var serverRes, result, err_3;
1586
+ var serverRes, startMs, result, err_3, durationMs;
1504
1587
  var _a;
1505
1588
  return __generator(this, function (_b) {
1506
1589
  switch (_b.label) {
@@ -1510,9 +1593,10 @@ var ResolveIOMainServer = /** @class */ (function () {
1510
1593
  hasError: false,
1511
1594
  data: null
1512
1595
  };
1596
+ startMs = Date.now();
1513
1597
  _b.label = 1;
1514
1598
  case 1:
1515
- _b.trys.push([1, 3, , 4]);
1599
+ _b.trys.push([1, 3, 4, 5]);
1516
1600
  return [4 /*yield*/, (_a = this._methodManager.callMethod).call.apply(_a, __spreadArray([Object.assign({}, this._methodManager, method_manager_1.MethodManager.prototype, {
1517
1601
  id_user: ws['id_user'],
1518
1602
  user: ws['user'],
@@ -1522,13 +1606,26 @@ var ResolveIOMainServer = /** @class */ (function () {
1522
1606
  case 2:
1523
1607
  result = _b.sent();
1524
1608
  serverRes.data = result;
1525
- return [3 /*break*/, 4];
1609
+ return [3 /*break*/, 5];
1526
1610
  case 3:
1527
1611
  err_3 = _b.sent();
1528
1612
  serverRes.hasError = true;
1529
1613
  serverRes.data = err_3 || 'Unknown error';
1530
- return [3 /*break*/, 4];
1614
+ return [3 /*break*/, 5];
1531
1615
  case 4:
1616
+ durationMs = Date.now() - startMs;
1617
+ if (durationMs >= this._slowHandlerThresholdMs) {
1618
+ console.log(new Date(), '[Slow Local Method]', {
1619
+ durationMs: durationMs,
1620
+ method: method,
1621
+ route: route || null,
1622
+ id_user: ws['id_user'] || null,
1623
+ user: ws['user'] || null,
1624
+ id_ws: ws['id_socket'] || null
1625
+ });
1626
+ }
1627
+ return [7 /*endfinally*/];
1628
+ case 5:
1532
1629
  if (ws && ws.readyState === ws.OPEN) {
1533
1630
  this._websocketManager.send(ws, serverRes);
1534
1631
  }