@resolveio/server-lib 20.14.13 → 20.14.15

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.
@@ -48,6 +48,7 @@ export declare class SubscriptionManager {
48
48
  private _latencyFlushPending;
49
49
  private readonly LATENCY_UPDATE_INTERVAL;
50
50
  private readonly LATENCY_UPDATE_THRESHOLD_MS;
51
+ private readonly LATENCY_DEBUG_THRESHOLD_MS;
51
52
  private _invalidationDebounceTimers;
52
53
  private _invalidationPendingTimestamps;
53
54
  private _pendingInvalidations;
@@ -79,6 +80,7 @@ export declare class SubscriptionManager {
79
80
  private resolveLocalOplogResyncIntervalMs;
80
81
  private parsePositiveNumber;
81
82
  private isChangeStreamUnsupported;
83
+ private isResumeTokenInvalid;
82
84
  private enableLocalOplogFallback;
83
85
  getUseLocalOplog(): boolean;
84
86
  notifyLocalOplog(collection: string, type?: string): void;
@@ -159,6 +159,7 @@ var SubscriptionManager = /** @class */ (function () {
159
159
  this.LATENCY_UPDATE_INTERVAL = 60000;
160
160
  // Minimum time difference between two latency updates for the same user
161
161
  this.LATENCY_UPDATE_THRESHOLD_MS = 30000;
162
+ this.LATENCY_DEBUG_THRESHOLD_MS = 1000;
162
163
  // private currentPerfomanceMonitor: CurrentPerformanceMonitor[] = [];
163
164
  // private idPerformance: number = 0;
164
165
  // private performanceThread;
@@ -667,20 +668,55 @@ var SubscriptionManager = /** @class */ (function () {
667
668
  };
668
669
  // Throttled `loggedInLatency` method
669
670
  SubscriptionManager.prototype.loggedInLatency = function (ws) {
670
- var loggedInUser = this._loggedInUsers.find(function (a) { return a.id_ws === ws['id_socket']; });
671
- if (!loggedInUser)
672
- return;
671
+ var _a, _b, _c, _d;
673
672
  var now = new Date();
674
- var existingEntry = this.latencyBuffer.get(ws['id_socket']);
675
673
  var newLatency = ws['latency'];
674
+ var socketId = ws['id_socket'];
675
+ var loggedInUser = this._loggedInUsers.find(function (a) { return a.id_ws === socketId; });
676
+ if (!loggedInUser) {
677
+ if (typeof newLatency === 'number' && newLatency >= this.LATENCY_DEBUG_THRESHOLD_MS) {
678
+ var lastRoute = this._lastRouteBySocket.get(socketId);
679
+ var workerDispatcher = (_b = (_a = resolveio_server_app_1.ResolveIOServer.getMainServer()) === null || _a === void 0 ? void 0 : _a.getWorkerDispatcherManager) === null || _b === void 0 ? void 0 : _b.call(_a);
680
+ var workerSnapshot = workerDispatcher && typeof workerDispatcher.getQueueSnapshot === 'function'
681
+ ? workerDispatcher.getQueueSnapshot()
682
+ : null;
683
+ console.log(new Date(), '[Latency Spike]', {
684
+ latencyMs: (0, common_1.round)(newLatency),
685
+ id_user: ws['id_user'] || null,
686
+ user: ws['user'] || null,
687
+ id_ws: socketId,
688
+ lastRoute: (lastRoute === null || lastRoute === void 0 ? void 0 : lastRoute.route) || null,
689
+ lastRouteAgeMs: lastRoute ? (Date.now() - lastRoute.dateMs) : null,
690
+ worker: workerSnapshot
691
+ });
692
+ }
693
+ return;
694
+ }
695
+ var existingEntry = this.latencyBuffer.get(socketId);
676
696
  // Throttle updates: only update if time threshold has passed or latency has significantly changed
677
697
  if (!existingEntry ||
678
698
  (now.getTime() - existingEntry.lastUpdate.getTime() >= this.LATENCY_UPDATE_THRESHOLD_MS) ||
679
699
  (Math.abs(newLatency - existingEntry.latency) > 100) // Optional: log only significant changes
680
700
  ) {
701
+ if (typeof newLatency === 'number' && newLatency >= this.LATENCY_DEBUG_THRESHOLD_MS) {
702
+ var lastRoute = this._lastRouteBySocket.get(socketId);
703
+ var workerDispatcher = (_d = (_c = resolveio_server_app_1.ResolveIOServer.getMainServer()) === null || _c === void 0 ? void 0 : _c.getWorkerDispatcherManager) === null || _d === void 0 ? void 0 : _d.call(_c);
704
+ var workerSnapshot = workerDispatcher && typeof workerDispatcher.getQueueSnapshot === 'function'
705
+ ? workerDispatcher.getQueueSnapshot()
706
+ : null;
707
+ console.log(new Date(), '[Latency Spike]', {
708
+ latencyMs: (0, common_1.round)(newLatency),
709
+ id_user: loggedInUser.id_user,
710
+ user: loggedInUser.user,
711
+ id_ws: socketId,
712
+ lastRoute: (lastRoute === null || lastRoute === void 0 ? void 0 : lastRoute.route) || null,
713
+ lastRouteAgeMs: lastRoute ? (Date.now() - lastRoute.dateMs) : null,
714
+ worker: workerSnapshot
715
+ });
716
+ }
681
717
  // Update in-memory and buffer
682
718
  loggedInUser.date = now;
683
- this.latencyBuffer.set(ws['id_socket'], { latency: newLatency, lastUpdate: now });
719
+ this.latencyBuffer.set(socketId, { latency: newLatency, lastUpdate: now });
684
720
  }
685
721
  };
686
722
  // Method to flush buffered latency updates in bulk
@@ -1038,6 +1074,29 @@ var SubscriptionManager = /** @class */ (function () {
1038
1074
  }
1039
1075
  return false;
1040
1076
  };
1077
+ SubscriptionManager.prototype.isResumeTokenInvalid = function (error) {
1078
+ var code = typeof (error === null || error === void 0 ? void 0 : error.code) === 'number' ? error.code : null;
1079
+ var codeName = typeof (error === null || error === void 0 ? void 0 : error.codeName) === 'string' ? error.codeName.toLowerCase() : '';
1080
+ var message = typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' ? error.message.toLowerCase() : '';
1081
+ if (code === 286) {
1082
+ // ChangeStreamHistoryLost
1083
+ return true;
1084
+ }
1085
+ if (codeName.includes('changestreamhistorylost')) {
1086
+ return true;
1087
+ }
1088
+ if (message.includes('resume token') && (message.includes('not found') ||
1089
+ message.includes('not possible') ||
1090
+ message.includes('no longer') ||
1091
+ message.includes('not in the oplog') ||
1092
+ message.includes('too old'))) {
1093
+ return true;
1094
+ }
1095
+ if (message.includes('resume of change stream') && message.includes('not possible')) {
1096
+ return true;
1097
+ }
1098
+ return false;
1099
+ };
1041
1100
  SubscriptionManager.prototype.enableLocalOplogFallback = function (reason, error) {
1042
1101
  return __awaiter(this, void 0, void 0, function () {
1043
1102
  var _a, message;
@@ -1571,8 +1630,16 @@ var SubscriptionManager = /** @class */ (function () {
1571
1630
  case 1:
1572
1631
  _a.sent();
1573
1632
  return [2 /*return*/];
1574
- case 2: return [4 /*yield*/, this._oplog$.close()];
1633
+ case 2:
1634
+ if (!this.isResumeTokenInvalid(error)) return [3 /*break*/, 4];
1635
+ return [4 /*yield*/, this.clearResumeToken()];
1575
1636
  case 3:
1637
+ _a.sent();
1638
+ lastResumeToken_1 = null;
1639
+ this.queueFullResync('oplog-resume-token-invalid');
1640
+ _a.label = 4;
1641
+ case 4: return [4 /*yield*/, this._oplog$.close()];
1642
+ case 5:
1576
1643
  _a.sent();
1577
1644
  return [2 /*return*/];
1578
1645
  }