@resolveio/server-lib 20.14.19 → 20.14.22

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.
@@ -75,6 +75,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
75
75
  exports.SubscriptionManager = void 0;
76
76
  var NodeCache = require("node-cache");
77
77
  var msgpackr_1 = require("msgpackr");
78
+ var os = require("os");
79
+ var perf_hooks_1 = require("perf_hooks");
78
80
  var flag_collection_1 = require("../collections/flag.collection");
79
81
  var logged_in_users_collection_1 = require("../collections/logged-in-users.collection");
80
82
  var app_status_1 = require("../publications/app-status");
@@ -170,7 +172,46 @@ var SubscriptionManager = /** @class */ (function () {
170
172
  this._pendingInvalidations = new Map();
171
173
  this.DEBOUNCE_DELAY = 100; // 100ms debounce window
172
174
  this.MAX_WAIT_TIME = 500; // 500ms maximum delay
175
+ this._warmupEnabled = false;
176
+ this._warmupEndsAtMs = 0;
177
+ this._warmupQueue = [];
178
+ this._warmupQueueKeys = new Set();
179
+ this._warmupTimer = null;
180
+ this._warmupInFlight = 0;
181
+ this._warmupProcessing = false;
182
+ this._warmupMaxInFlight = 2;
183
+ this._warmupMaxPerTick = 2;
184
+ this._warmupTickMs = 200;
185
+ this._warmupQueueLimit = 0;
186
+ this._warmupLogIntervalMs = 10000;
187
+ this._warmupLastLogMs = 0;
188
+ this._warmupAllowPublications = new Set();
189
+ this._warmupRampMaxPerTick = 0;
190
+ this._warmupRampMaxInFlight = 0;
191
+ this._warmupWindowEndedLogged = false;
192
+ this._warmupAdaptiveEnabled = true;
193
+ this._warmupAdaptiveSampleMs = 1000;
194
+ this._warmupAdaptiveAlpha = 0.2;
195
+ this._warmupTargetCpuPct = 55;
196
+ this._warmupMaxCpuPct = 85;
197
+ this._warmupTargetMemPct = 70;
198
+ this._warmupMaxMemPct = 85;
199
+ this._warmupTargetLagMs = 80;
200
+ this._warmupMaxLagMs = 200;
201
+ this._warmupAdaptiveScale = 0;
202
+ this._warmupAdaptiveLastSampleAt = 0;
203
+ this._warmupAdaptiveMetrics = { cpuPct: 0, memPct: 0, rssMB: 0, lagMs: 0, pressure: 0 };
204
+ this._warmupCpuSampleUsage = process.cpuUsage();
205
+ this._warmupCpuSampleAt = process.hrtime.bigint();
206
+ this._warmupLagMonitor = null;
207
+ this._publicationWorkersEnabled = true;
208
+ this._publicationWorkerQueueLimit = 0;
173
209
  }
210
+ SubscriptionManager.createPublicationRegistry = function (serverConfig) {
211
+ var subscriptionManager = new SubscriptionManager();
212
+ subscriptionManager.initializePublicationRegistry(serverConfig);
213
+ return subscriptionManager;
214
+ };
174
215
  SubscriptionManager.create = function (wss, serverConfig, monitorManagerFunction) {
175
216
  var _this = this;
176
217
  var subscriptionManager = new SubscriptionManager();
@@ -186,6 +227,10 @@ var SubscriptionManager = /** @class */ (function () {
186
227
  }); });
187
228
  return subscriptionManager;
188
229
  };
230
+ SubscriptionManager.prototype.initializePublicationRegistry = function (serverConfig) {
231
+ this.serverConfig = serverConfig || resolveio_server_app_1.ResolveIOServer.getServerConfig();
232
+ this.registerCorePublications();
233
+ };
189
234
  SubscriptionManager.prototype.initialize = function (wss, serverConfig, monitorManagerFunction) {
190
235
  return __awaiter(this, void 0, void 0, function () {
191
236
  var resumeToken, flag, dependencyFlag;
@@ -216,21 +261,7 @@ var SubscriptionManager = /** @class */ (function () {
216
261
  this._wss = wss;
217
262
  this._oplogMode = this.resolveOplogMode();
218
263
  this._localOplogResyncIntervalMs = this.resolveLocalOplogResyncIntervalMs();
219
- // Publications
220
- (0, super_admin_1.loadSuperAdminPublications)(this);
221
- (0, ai_terminal_1.loadAiTerminalPublications)(this);
222
- (0, app_status_1.loadAppStatusPublications)(this);
223
- (0, logs_1.loadLogPublications)(this);
224
- (0, files_1.loadFilePublications)(this);
225
- (0, cron_jobs_1.loadCronJobPublications)(this);
226
- (0, flags_update_1.loadFlagsUpdatePublications)(this);
227
- (0, flags_1.loadFlagsPublications)(this);
228
- (0, notifications_1.loadNotificationPublications)(this);
229
- (0, report_builder_reports_1.loadReportBuilderReportPublications)(this);
230
- (0, report_builder_libraries_1.loadReportBuilderLibraryPublications)(this);
231
- (0, user_groups_1.loadUserGroupPublications)(this);
232
- (0, user_guides_1.loadUserGuidePublications)(this);
233
- (0, report_builder_dashboard_builders_1.loadReportBuilderDashboardBuilderPublications)(this);
264
+ this.registerCorePublications();
234
265
  if (!(this._oplogMode === 'local')) return [3 /*break*/, 2];
235
266
  return [4 /*yield*/, this.enableLocalOplogFallback('config')];
236
267
  case 1:
@@ -368,11 +399,29 @@ var SubscriptionManager = /** @class */ (function () {
368
399
  this._enableDependencyDebug = process.env.ENABLE_DEPENDENCY_DEBUG === 'true';
369
400
  }
370
401
  this.setCacheLimit();
402
+ this.configureWarmup();
403
+ this.configurePublicationWorkers();
371
404
  return [2 /*return*/];
372
405
  }
373
406
  });
374
407
  });
375
408
  };
409
+ SubscriptionManager.prototype.registerCorePublications = function () {
410
+ (0, super_admin_1.loadSuperAdminPublications)(this);
411
+ (0, ai_terminal_1.loadAiTerminalPublications)(this);
412
+ (0, app_status_1.loadAppStatusPublications)(this);
413
+ (0, logs_1.loadLogPublications)(this);
414
+ (0, files_1.loadFilePublications)(this);
415
+ (0, cron_jobs_1.loadCronJobPublications)(this);
416
+ (0, flags_update_1.loadFlagsUpdatePublications)(this);
417
+ (0, flags_1.loadFlagsPublications)(this);
418
+ (0, notifications_1.loadNotificationPublications)(this);
419
+ (0, report_builder_reports_1.loadReportBuilderReportPublications)(this);
420
+ (0, report_builder_libraries_1.loadReportBuilderLibraryPublications)(this);
421
+ (0, user_groups_1.loadUserGroupPublications)(this);
422
+ (0, user_guides_1.loadUserGuidePublications)(this);
423
+ (0, report_builder_dashboard_builders_1.loadReportBuilderDashboardBuilderPublications)(this);
424
+ };
376
425
  SubscriptionManager.prototype.setCacheLimit = function () {
377
426
  if (process.env.IS_WORKERS_ENABLED === 'true') {
378
427
  this._heapLimit = this._heapSize * 0.4;
@@ -381,6 +430,438 @@ var SubscriptionManager = /** @class */ (function () {
381
430
  this._heapLimit = this._heapSize * 0.3; // Use 50% of total heap size
382
431
  }
383
432
  };
433
+ SubscriptionManager.prototype.configureWarmup = function () {
434
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
435
+ var config = this.serverConfig || resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
436
+ var enabledRaw = (_a = process.env.SUBSCRIPTION_WARMUP_ENABLED) !== null && _a !== void 0 ? _a : config['SUBSCRIPTION_WARMUP_ENABLED'];
437
+ var warmupMs = this.parsePositiveNumber((_b = process.env.SUBSCRIPTION_WARMUP_MS) !== null && _b !== void 0 ? _b : config['SUBSCRIPTION_WARMUP_MS']);
438
+ var enabled = this.parseBoolean(enabledRaw) || warmupMs > 0;
439
+ if (!enabled) {
440
+ this._warmupEnabled = false;
441
+ return;
442
+ }
443
+ var durationMs = warmupMs || 60000;
444
+ this._warmupEnabled = true;
445
+ this._warmupEndsAtMs = Date.now() + durationMs;
446
+ this._warmupTickMs = this.parsePositiveNumber((_c = process.env.SUBSCRIPTION_WARMUP_TICK_MS) !== null && _c !== void 0 ? _c : config['SUBSCRIPTION_WARMUP_TICK_MS']) || this._warmupTickMs;
447
+ this._warmupMaxPerTick = this.parsePositiveNumber((_d = process.env.SUBSCRIPTION_WARMUP_MAX_PER_TICK) !== null && _d !== void 0 ? _d : config['SUBSCRIPTION_WARMUP_MAX_PER_TICK']) || this._warmupMaxPerTick;
448
+ this._warmupMaxInFlight = this.parsePositiveNumber((_e = process.env.SUBSCRIPTION_WARMUP_MAX_IN_FLIGHT) !== null && _e !== void 0 ? _e : config['SUBSCRIPTION_WARMUP_MAX_IN_FLIGHT']) || Math.max(1, this._warmupMaxPerTick);
449
+ this._warmupRampMaxPerTick = this.parsePositiveNumber((_f = process.env.SUBSCRIPTION_WARMUP_RAMP_MAX_PER_TICK) !== null && _f !== void 0 ? _f : config['SUBSCRIPTION_WARMUP_RAMP_MAX_PER_TICK']) || this._warmupMaxPerTick;
450
+ this._warmupRampMaxInFlight = this.parsePositiveNumber((_g = process.env.SUBSCRIPTION_WARMUP_RAMP_MAX_IN_FLIGHT) !== null && _g !== void 0 ? _g : config['SUBSCRIPTION_WARMUP_RAMP_MAX_IN_FLIGHT']) || this._warmupMaxInFlight;
451
+ this._warmupQueueLimit = this.parsePositiveNumber((_h = process.env.SUBSCRIPTION_WARMUP_QUEUE_LIMIT) !== null && _h !== void 0 ? _h : config['SUBSCRIPTION_WARMUP_QUEUE_LIMIT']) || this._warmupQueueLimit;
452
+ this._warmupLogIntervalMs = this.parsePositiveNumber((_j = process.env.SUBSCRIPTION_WARMUP_LOG_INTERVAL_MS) !== null && _j !== void 0 ? _j : config['SUBSCRIPTION_WARMUP_LOG_INTERVAL_MS']) || this._warmupLogIntervalMs;
453
+ var adaptiveRaw = (_k = process.env.SUBSCRIPTION_WARMUP_ADAPTIVE_ENABLED) !== null && _k !== void 0 ? _k : config['SUBSCRIPTION_WARMUP_ADAPTIVE_ENABLED'];
454
+ this._warmupAdaptiveEnabled = adaptiveRaw === undefined ? true : this.parseBoolean(adaptiveRaw);
455
+ this._warmupAdaptiveSampleMs = this.parsePositiveNumber((_l = process.env.SUBSCRIPTION_WARMUP_ADAPTIVE_SAMPLE_MS) !== null && _l !== void 0 ? _l : config['SUBSCRIPTION_WARMUP_ADAPTIVE_SAMPLE_MS']) || this._warmupAdaptiveSampleMs;
456
+ this._warmupAdaptiveAlpha = this.parsePositiveFloat((_m = process.env.SUBSCRIPTION_WARMUP_ADAPTIVE_ALPHA) !== null && _m !== void 0 ? _m : config['SUBSCRIPTION_WARMUP_ADAPTIVE_ALPHA']) || this._warmupAdaptiveAlpha;
457
+ this._warmupTargetCpuPct = this.parsePositiveNumber((_o = process.env.SUBSCRIPTION_WARMUP_TARGET_CPU_PCT) !== null && _o !== void 0 ? _o : config['SUBSCRIPTION_WARMUP_TARGET_CPU_PCT']) || this._warmupTargetCpuPct;
458
+ this._warmupMaxCpuPct = this.parsePositiveNumber((_p = process.env.SUBSCRIPTION_WARMUP_MAX_CPU_PCT) !== null && _p !== void 0 ? _p : config['SUBSCRIPTION_WARMUP_MAX_CPU_PCT']) || this._warmupMaxCpuPct;
459
+ this._warmupTargetMemPct = this.parsePositiveNumber((_q = process.env.SUBSCRIPTION_WARMUP_TARGET_MEM_PCT) !== null && _q !== void 0 ? _q : config['SUBSCRIPTION_WARMUP_TARGET_MEM_PCT']) || this._warmupTargetMemPct;
460
+ this._warmupMaxMemPct = this.parsePositiveNumber((_r = process.env.SUBSCRIPTION_WARMUP_MAX_MEM_PCT) !== null && _r !== void 0 ? _r : config['SUBSCRIPTION_WARMUP_MAX_MEM_PCT']) || this._warmupMaxMemPct;
461
+ this._warmupTargetLagMs = this.parsePositiveNumber((_s = process.env.SUBSCRIPTION_WARMUP_TARGET_LAG_MS) !== null && _s !== void 0 ? _s : config['SUBSCRIPTION_WARMUP_TARGET_LAG_MS']) || this._warmupTargetLagMs;
462
+ this._warmupMaxLagMs = this.parsePositiveNumber((_t = process.env.SUBSCRIPTION_WARMUP_MAX_LAG_MS) !== null && _t !== void 0 ? _t : config['SUBSCRIPTION_WARMUP_MAX_LAG_MS']) || this._warmupMaxLagMs;
463
+ this._warmupAdaptiveScale = 0;
464
+ this._warmupAdaptiveLastSampleAt = 0;
465
+ this._warmupWindowEndedLogged = false;
466
+ if (this._warmupAdaptiveEnabled) {
467
+ this.ensureWarmupAdaptiveMonitor();
468
+ }
469
+ var allowRaw = (_u = process.env.SUBSCRIPTION_WARMUP_ALLOW_PUBS) !== null && _u !== void 0 ? _u : config['SUBSCRIPTION_WARMUP_ALLOW_PUBS'];
470
+ if (typeof allowRaw === 'string' && allowRaw.trim()) {
471
+ this._warmupAllowPublications = new Set(allowRaw
472
+ .split(',')
473
+ .map(function (entry) { return entry.trim(); })
474
+ .filter(Boolean));
475
+ }
476
+ this.startWarmupTimer();
477
+ console.log(new Date(), 'Sub Manager', 'Warmup enabled', {
478
+ durationMs: durationMs,
479
+ tickMs: this._warmupTickMs,
480
+ maxPerTick: this._warmupMaxPerTick,
481
+ maxInFlight: this._warmupMaxInFlight,
482
+ rampMaxPerTick: this._warmupRampMaxPerTick,
483
+ rampMaxInFlight: this._warmupRampMaxInFlight,
484
+ adaptiveEnabled: this._warmupAdaptiveEnabled,
485
+ adaptiveSampleMs: this._warmupAdaptiveSampleMs,
486
+ adaptiveAlpha: this._warmupAdaptiveAlpha,
487
+ targetCpuPct: this._warmupTargetCpuPct,
488
+ maxCpuPct: this._warmupMaxCpuPct,
489
+ targetMemPct: this._warmupTargetMemPct,
490
+ maxMemPct: this._warmupMaxMemPct,
491
+ targetLagMs: this._warmupTargetLagMs,
492
+ maxLagMs: this._warmupMaxLagMs,
493
+ queueLimit: this._warmupQueueLimit,
494
+ allowPubs: Array.from(this._warmupAllowPublications.values())
495
+ });
496
+ };
497
+ SubscriptionManager.prototype.configurePublicationWorkers = function () {
498
+ var _a, _b;
499
+ var config = this.serverConfig || resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
500
+ var enabledRaw = (_a = process.env.SUBSCRIPTION_WORKERS_ENABLED) !== null && _a !== void 0 ? _a : config['SUBSCRIPTION_WORKERS_ENABLED'];
501
+ this._publicationWorkersEnabled = enabledRaw === undefined ? true : this.parseBoolean(enabledRaw);
502
+ this._publicationWorkerQueueLimit = this.parsePositiveNumber((_b = process.env.SUBSCRIPTION_WORKER_QUEUE_MAX) !== null && _b !== void 0 ? _b : config['SUBSCRIPTION_WORKER_QUEUE_MAX']);
503
+ };
504
+ SubscriptionManager.prototype.parseBoolean = function (value) {
505
+ if (value === true) {
506
+ return true;
507
+ }
508
+ if (value === false || value === null || value === undefined) {
509
+ return false;
510
+ }
511
+ if (typeof value === 'number') {
512
+ return value === 1;
513
+ }
514
+ if (typeof value === 'string') {
515
+ var normalized = value.trim().toLowerCase();
516
+ return ['1', 'true', 'yes', 'y', 'on'].includes(normalized);
517
+ }
518
+ return false;
519
+ };
520
+ SubscriptionManager.prototype.clampNumber = function (value, min, max) {
521
+ if (value < min) {
522
+ return min;
523
+ }
524
+ if (value > max) {
525
+ return max;
526
+ }
527
+ return value;
528
+ };
529
+ SubscriptionManager.prototype.ensureWarmupAdaptiveMonitor = function () {
530
+ if (this._warmupLagMonitor) {
531
+ return;
532
+ }
533
+ this._warmupLagMonitor = (0, perf_hooks_1.monitorEventLoopDelay)({ resolution: 20 });
534
+ this._warmupLagMonitor.enable();
535
+ this._warmupCpuSampleUsage = process.cpuUsage();
536
+ this._warmupCpuSampleAt = process.hrtime.bigint();
537
+ this._warmupAdaptiveLastSampleAt = Date.now();
538
+ };
539
+ SubscriptionManager.prototype.normalizePressure = function (value, target, max) {
540
+ if (!Number.isFinite(value)) {
541
+ return 0;
542
+ }
543
+ if (max <= target) {
544
+ return value > target ? 1 : 0;
545
+ }
546
+ var pressure = (value - target) / (max - target);
547
+ return this.clampNumber(pressure, 0, 1);
548
+ };
549
+ SubscriptionManager.prototype.sampleCpuPercent = function () {
550
+ var _a, _b, _c;
551
+ var usage = process.cpuUsage();
552
+ var now = process.hrtime.bigint();
553
+ var elapsedMicros = Number(now - this._warmupCpuSampleAt) / 1000;
554
+ var usageDelta = (usage.user - this._warmupCpuSampleUsage.user) + (usage.system - this._warmupCpuSampleUsage.system);
555
+ this._warmupCpuSampleUsage = usage;
556
+ this._warmupCpuSampleAt = now;
557
+ if (!elapsedMicros || elapsedMicros <= 0) {
558
+ return (_b = (_a = this._warmupAdaptiveMetrics) === null || _a === void 0 ? void 0 : _a.cpuPct) !== null && _b !== void 0 ? _b : 0;
559
+ }
560
+ var cores = Math.max(1, ((_c = os.cpus()) === null || _c === void 0 ? void 0 : _c.length) || 1);
561
+ var cpuPct = (usageDelta / (elapsedMicros * cores)) * 100;
562
+ return this.clampNumber(cpuPct, 0, 100);
563
+ };
564
+ SubscriptionManager.prototype.sampleWarmupAdaptiveMetrics = function (nowMs) {
565
+ if (!this._warmupAdaptiveEnabled) {
566
+ return this._warmupAdaptiveMetrics;
567
+ }
568
+ if (this._warmupAdaptiveLastSampleAt && (nowMs - this._warmupAdaptiveLastSampleAt) < this._warmupAdaptiveSampleMs) {
569
+ return this._warmupAdaptiveMetrics;
570
+ }
571
+ this.ensureWarmupAdaptiveMonitor();
572
+ var cpuPct = this.sampleCpuPercent();
573
+ var mem = process.memoryUsage();
574
+ var totalMem = os.totalmem();
575
+ var rssMB = mem.rss / (1024 * 1024);
576
+ var rssPct = totalMem > 0 ? (mem.rss / totalMem) * 100 : 0;
577
+ var systemMemPct = totalMem > 0 ? ((totalMem - os.freemem()) / totalMem) * 100 : 0;
578
+ var memPct = this.clampNumber(Math.max(rssPct, systemMemPct), 0, 100);
579
+ var lagMs = 0;
580
+ if (this._warmupLagMonitor) {
581
+ lagMs = this._warmupLagMonitor.percentile(99) / 1e6;
582
+ this._warmupLagMonitor.reset();
583
+ }
584
+ var cpuPressure = this.normalizePressure(cpuPct, this._warmupTargetCpuPct, this._warmupMaxCpuPct);
585
+ var memPressure = this.normalizePressure(memPct, this._warmupTargetMemPct, this._warmupMaxMemPct);
586
+ var lagPressure = this.normalizePressure(lagMs, this._warmupTargetLagMs, this._warmupMaxLagMs);
587
+ var pressure = Math.max(cpuPressure, memPressure, lagPressure);
588
+ this._warmupAdaptiveMetrics = {
589
+ cpuPct: cpuPct,
590
+ memPct: memPct,
591
+ rssMB: rssMB,
592
+ lagMs: lagMs,
593
+ pressure: pressure
594
+ };
595
+ this._warmupAdaptiveLastSampleAt = nowMs;
596
+ return this._warmupAdaptiveMetrics;
597
+ };
598
+ SubscriptionManager.prototype.updateAdaptiveScale = function (targetScale) {
599
+ var alpha = this.clampNumber(this._warmupAdaptiveAlpha, 0, 1);
600
+ if (!Number.isFinite(this._warmupAdaptiveScale)) {
601
+ this._warmupAdaptiveScale = targetScale;
602
+ return this._warmupAdaptiveScale;
603
+ }
604
+ this._warmupAdaptiveScale = this.clampNumber((alpha * targetScale) + ((1 - alpha) * this._warmupAdaptiveScale), 0, 1);
605
+ return this._warmupAdaptiveScale;
606
+ };
607
+ SubscriptionManager.prototype.isWarmupGateActive = function () {
608
+ if (!this._warmupEnabled) {
609
+ return false;
610
+ }
611
+ return true;
612
+ };
613
+ SubscriptionManager.prototype.shouldQueueWarmup = function (publication, messageRoute) {
614
+ if (!this.isWarmupGateActive()) {
615
+ return false;
616
+ }
617
+ if (messageRoute === 'Bypass') {
618
+ return false;
619
+ }
620
+ if (this._warmupAllowPublications.has(publication)) {
621
+ return false;
622
+ }
623
+ return true;
624
+ };
625
+ SubscriptionManager.prototype.buildWarmupKey = function (socketId, messageId, publication, subscriptionData) {
626
+ var normalizedSubscriptionData = Array.isArray(subscriptionData) ? subscriptionData : [];
627
+ return "".concat(socketId, ":").concat(messageId, ":").concat(publication, ":").concat(JSON.stringify(normalizedSubscriptionData));
628
+ };
629
+ SubscriptionManager.prototype.queueWarmupSubscription = function (params) {
630
+ var _a;
631
+ if (!this.isWarmupGateActive()) {
632
+ return false;
633
+ }
634
+ if (this._warmupQueueLimit > 0 && this._warmupQueue.length >= this._warmupQueueLimit) {
635
+ if (this._enableDebug) {
636
+ console.log(new Date(), 'Sub Manager', 'Warmup queue full; processing immediately', this._warmupQueue.length);
637
+ }
638
+ return false;
639
+ }
640
+ var socketId = (_a = params.ws) === null || _a === void 0 ? void 0 : _a['id_socket'];
641
+ if (!socketId) {
642
+ return false;
643
+ }
644
+ var key = this.buildWarmupKey(socketId, params.messageId, params.publication, params.subscriptionData);
645
+ if (this._warmupQueueKeys.has(key)) {
646
+ return true;
647
+ }
648
+ this._warmupQueue.push({
649
+ key: key,
650
+ socketId: socketId,
651
+ messageRoute: params.messageRoute,
652
+ messageDate: params.messageDate,
653
+ messageId: params.messageId,
654
+ publication: params.publication,
655
+ subscriptionData: params.subscriptionData,
656
+ enqueuedAt: Date.now()
657
+ });
658
+ this._warmupQueueKeys.add(key);
659
+ this.startWarmupTimer();
660
+ this.logWarmupStatus('queued');
661
+ return true;
662
+ };
663
+ SubscriptionManager.prototype.startWarmupTimer = function () {
664
+ var _this = this;
665
+ if (this._warmupTimer) {
666
+ return;
667
+ }
668
+ this._warmupTimer = setInterval(function () { return __awaiter(_this, void 0, void 0, function () {
669
+ var error_1;
670
+ return __generator(this, function (_a) {
671
+ switch (_a.label) {
672
+ case 0:
673
+ _a.trys.push([0, 2, , 3]);
674
+ return [4 /*yield*/, this.processWarmupQueue()];
675
+ case 1:
676
+ _a.sent();
677
+ return [3 /*break*/, 3];
678
+ case 2:
679
+ error_1 = _a.sent();
680
+ console.error(new Date(), 'Sub Manager', 'Warmup queue processing failed', error_1);
681
+ return [3 /*break*/, 3];
682
+ case 3: return [2 /*return*/];
683
+ }
684
+ });
685
+ }); }, this._warmupTickMs);
686
+ };
687
+ SubscriptionManager.prototype.stopWarmupTimerIfIdle = function () {
688
+ if (!this._warmupTimer) {
689
+ return;
690
+ }
691
+ if (this._warmupQueue.length > 0 || this._warmupInFlight > 0) {
692
+ return;
693
+ }
694
+ clearInterval(this._warmupTimer);
695
+ this._warmupTimer = null;
696
+ };
697
+ SubscriptionManager.prototype.processWarmupQueue = function () {
698
+ return __awaiter(this, void 0, void 0, function () {
699
+ var pendingTasks, now, limits, processed, _loop_3, this_3, state_1;
700
+ var _a;
701
+ return __generator(this, function (_b) {
702
+ switch (_b.label) {
703
+ case 0:
704
+ if (this._warmupProcessing) {
705
+ return [2 /*return*/];
706
+ }
707
+ this._warmupProcessing = true;
708
+ _b.label = 1;
709
+ case 1:
710
+ _b.trys.push([1, , 4, 5]);
711
+ pendingTasks = [];
712
+ now = Date.now();
713
+ if (this._warmupEnabled && now >= this._warmupEndsAtMs && !this._warmupWindowEndedLogged) {
714
+ this._warmupWindowEndedLogged = true;
715
+ console.log(new Date(), 'Sub Manager', 'Warmup minimum window ended', {
716
+ queued: this._warmupQueue.length
717
+ });
718
+ }
719
+ if (!this._warmupQueue.length) {
720
+ this.stopWarmupTimerIfIdle();
721
+ return [2 /*return*/];
722
+ }
723
+ limits = this.getWarmupLimits(now);
724
+ processed = 0;
725
+ _loop_3 = function () {
726
+ var item = this_3._warmupQueue.shift();
727
+ if (!item) {
728
+ return "break";
729
+ }
730
+ this_3._warmupQueueKeys.delete(item.key);
731
+ var wasLastItem = this_3._warmupQueue.length === 0;
732
+ var ws = this_3._websocketManager.getWebSocket(item.socketId);
733
+ if (!ws || ws.readyState !== ws.OPEN) {
734
+ return "continue";
735
+ }
736
+ var normalizedSubscriptionData = Array.isArray(item.subscriptionData) ? item.subscriptionData : [];
737
+ var subscriptionKey = JSON.stringify(normalizedSubscriptionData);
738
+ var sub = this_3._subscriptions.find(function (a) { return a.publication === item.publication && a.subscriptionKey === subscriptionKey; });
739
+ if (!sub || !((_a = sub.clients) === null || _a === void 0 ? void 0 : _a.length)) {
740
+ return "continue";
741
+ }
742
+ if (sub.running) {
743
+ this_3.requeueWarmupItem(item);
744
+ processed += 1;
745
+ if (wasLastItem) {
746
+ return "break";
747
+ }
748
+ return "continue";
749
+ }
750
+ this_3._warmupInFlight += 1;
751
+ processed += 1;
752
+ pendingTasks.push(this_3.processWarmupItemWithCleanup(item, ws, sub));
753
+ };
754
+ this_3 = this;
755
+ while (this._warmupQueue.length &&
756
+ processed < limits.maxPerTick &&
757
+ this._warmupInFlight < limits.maxInFlight) {
758
+ state_1 = _loop_3();
759
+ if (state_1 === "break")
760
+ break;
761
+ }
762
+ this.logWarmupStatus('tick', limits);
763
+ if (!pendingTasks.length) return [3 /*break*/, 3];
764
+ return [4 /*yield*/, Promise.allSettled(pendingTasks)];
765
+ case 2:
766
+ _b.sent();
767
+ _b.label = 3;
768
+ case 3: return [3 /*break*/, 5];
769
+ case 4:
770
+ this._warmupProcessing = false;
771
+ return [7 /*endfinally*/];
772
+ case 5: return [2 /*return*/];
773
+ }
774
+ });
775
+ });
776
+ };
777
+ SubscriptionManager.prototype.processWarmupItem = function (item, ws, sub) {
778
+ return __awaiter(this, void 0, void 0, function () {
779
+ return __generator(this, function (_a) {
780
+ switch (_a.label) {
781
+ case 0: return [4 /*yield*/, this.processSubscription(sub, ws, item.messageId)];
782
+ case 1:
783
+ _a.sent();
784
+ return [2 /*return*/];
785
+ }
786
+ });
787
+ });
788
+ };
789
+ SubscriptionManager.prototype.processWarmupItemWithCleanup = function (item, ws, sub) {
790
+ return __awaiter(this, void 0, void 0, function () {
791
+ var error_2;
792
+ return __generator(this, function (_a) {
793
+ switch (_a.label) {
794
+ case 0:
795
+ _a.trys.push([0, 2, 3, 4]);
796
+ return [4 /*yield*/, this.processWarmupItem(item, ws, sub)];
797
+ case 1:
798
+ _a.sent();
799
+ return [3 /*break*/, 4];
800
+ case 2:
801
+ error_2 = _a.sent();
802
+ console.error(new Date(), 'Sub Manager', 'Warmup item failed', error_2);
803
+ return [3 /*break*/, 4];
804
+ case 3:
805
+ this._warmupInFlight -= 1;
806
+ this.stopWarmupTimerIfIdle();
807
+ return [7 /*endfinally*/];
808
+ case 4: return [2 /*return*/];
809
+ }
810
+ });
811
+ });
812
+ };
813
+ SubscriptionManager.prototype.getWarmupLimits = function (nowMs) {
814
+ var basePerTick = Math.max(1, this._warmupMaxPerTick);
815
+ var baseInFlight = Math.max(1, this._warmupMaxInFlight);
816
+ var targetPerTick = Math.max(basePerTick, this._warmupRampMaxPerTick || basePerTick);
817
+ var targetInFlight = Math.max(baseInFlight, this._warmupRampMaxInFlight || baseInFlight);
818
+ if (!this._warmupAdaptiveEnabled) {
819
+ return { maxPerTick: basePerTick, maxInFlight: baseInFlight, rampActive: false, rampProgress: 0 };
820
+ }
821
+ var metrics = this.sampleWarmupAdaptiveMetrics(nowMs);
822
+ var targetScale = this.clampNumber(1 - metrics.pressure, 0, 1);
823
+ var scale = this.updateAdaptiveScale(targetScale);
824
+ var maxPerTick = Math.max(1, (0, common_1.round)(basePerTick + (targetPerTick - basePerTick) * scale));
825
+ var maxInFlight = Math.max(1, (0, common_1.round)(baseInFlight + (targetInFlight - baseInFlight) * scale));
826
+ return { maxPerTick: maxPerTick, maxInFlight: maxInFlight, rampActive: true, rampProgress: scale, adaptiveScale: scale, metrics: metrics };
827
+ };
828
+ SubscriptionManager.prototype.requeueWarmupItem = function (item) {
829
+ if (this._warmupQueueKeys.has(item.key)) {
830
+ return;
831
+ }
832
+ item.enqueuedAt = Date.now();
833
+ this._warmupQueue.push(item);
834
+ this._warmupQueueKeys.add(item.key);
835
+ };
836
+ SubscriptionManager.prototype.logWarmupStatus = function (reason, limits) {
837
+ var _a, _b, _c;
838
+ if (!this._warmupLogIntervalMs) {
839
+ return;
840
+ }
841
+ var now = Date.now();
842
+ if (now - this._warmupLastLogMs < this._warmupLogIntervalMs) {
843
+ return;
844
+ }
845
+ this._warmupLastLogMs = now;
846
+ var metrics = limits === null || limits === void 0 ? void 0 : limits.metrics;
847
+ console.log(new Date(), 'Sub Manager', 'Warmup status', {
848
+ reason: reason,
849
+ enabled: this._warmupEnabled,
850
+ endsInMs: this._warmupEnabled ? Math.max(0, this._warmupEndsAtMs - now) : 0,
851
+ queued: this._warmupQueue.length,
852
+ inFlight: this._warmupInFlight,
853
+ maxPerTick: (_a = limits === null || limits === void 0 ? void 0 : limits.maxPerTick) !== null && _a !== void 0 ? _a : this._warmupMaxPerTick,
854
+ maxInFlight: (_b = limits === null || limits === void 0 ? void 0 : limits.maxInFlight) !== null && _b !== void 0 ? _b : this._warmupMaxInFlight,
855
+ rampActive: (_c = limits === null || limits === void 0 ? void 0 : limits.rampActive) !== null && _c !== void 0 ? _c : false,
856
+ rampProgress: typeof (limits === null || limits === void 0 ? void 0 : limits.rampProgress) === 'number' ? (0, common_1.round)(limits.rampProgress * 100) : 0,
857
+ adaptiveScale: typeof (limits === null || limits === void 0 ? void 0 : limits.adaptiveScale) === 'number' ? (0, common_1.round)(limits.adaptiveScale * 100) : 0,
858
+ cpuPct: metrics ? (0, common_1.round)(metrics.cpuPct) : undefined,
859
+ memPct: metrics ? (0, common_1.round)(metrics.memPct) : undefined,
860
+ rssMB: metrics ? (0, common_1.round)(metrics.rssMB) : undefined,
861
+ lagMs: metrics ? (0, common_1.round)(metrics.lagMs) : undefined,
862
+ pressure: metrics ? (0, common_1.round)(metrics.pressure * 100) : undefined
863
+ });
864
+ };
384
865
  SubscriptionManager.prototype.invalidatePubsCache = function (collection, type, documentId, document) {
385
866
  return __awaiter(this, void 0, void 0, function () {
386
867
  var queue, debounceKey, now, firstInvalidationTime, waitedTooLong;
@@ -598,6 +1079,141 @@ var SubscriptionManager = /** @class */ (function () {
598
1079
  this._lastRouteBySocket.set(socketId, { route: messageRoute, dateMs: messageDateMs });
599
1080
  return false;
600
1081
  };
1082
+ SubscriptionManager.prototype.getPublicationWorkerDispatcher = function () {
1083
+ var mainServer = resolveio_server_app_1.ResolveIOServer.getMainServer();
1084
+ return mainServer && typeof mainServer.getWorkerDispatcherManager === 'function'
1085
+ ? mainServer.getWorkerDispatcherManager()
1086
+ : null;
1087
+ };
1088
+ SubscriptionManager.prototype.shouldUsePublicationWorkers = function () {
1089
+ if (!this._publicationWorkersEnabled) {
1090
+ return false;
1091
+ }
1092
+ var dispatcher = this.getPublicationWorkerDispatcher();
1093
+ if (!dispatcher || !dispatcher.hasWorkers()) {
1094
+ return false;
1095
+ }
1096
+ if (this._publicationWorkerQueueLimit > 0) {
1097
+ var snapshot = dispatcher.getQueueSnapshot();
1098
+ if (snapshot.queueDepth >= this._publicationWorkerQueueLimit) {
1099
+ return false;
1100
+ }
1101
+ }
1102
+ return true;
1103
+ };
1104
+ SubscriptionManager.prototype.runPublicationViaWorker = function (sub, userId) {
1105
+ return __awaiter(this, void 0, void 0, function () {
1106
+ var dispatcher, response, meta, snapshot, error_3;
1107
+ return __generator(this, function (_a) {
1108
+ switch (_a.label) {
1109
+ case 0:
1110
+ if (!this.shouldUsePublicationWorkers()) {
1111
+ return [2 /*return*/, null];
1112
+ }
1113
+ dispatcher = this.getPublicationWorkerDispatcher();
1114
+ if (!dispatcher) {
1115
+ return [2 /*return*/, null];
1116
+ }
1117
+ _a.label = 1;
1118
+ case 1:
1119
+ _a.trys.push([1, 3, , 4]);
1120
+ return [4 /*yield*/, dispatcher.sendInternalPromiseRaw('runPublication', [
1121
+ sub.publication,
1122
+ sub.subscriptionData,
1123
+ userId
1124
+ ])];
1125
+ case 2:
1126
+ response = _a.sent();
1127
+ if (!response || response.error) {
1128
+ throw (response === null || response === void 0 ? void 0 : response.result) || new Error('Publication worker error');
1129
+ }
1130
+ if (!response.packedResult) {
1131
+ throw new Error('Publication worker missing packedResult');
1132
+ }
1133
+ meta = response.meta || {};
1134
+ snapshot = meta.snapshot ? (0, subscription_dependency_context_1.deserializeDependencySnapshot)(meta.snapshot) : undefined;
1135
+ return [2 /*return*/, {
1136
+ packedResult: response.packedResult,
1137
+ snapshot: snapshot,
1138
+ encoding: response.encoding || meta.encoding || 'msgpack',
1139
+ workerUsed: true
1140
+ }];
1141
+ case 3:
1142
+ error_3 = _a.sent();
1143
+ if (this._enableDebug) {
1144
+ console.log(new Date(), 'Sub Manager', 'Worker publication failed, falling back', sub.publication, (error_3 === null || error_3 === void 0 ? void 0 : error_3.message) || error_3);
1145
+ }
1146
+ return [2 /*return*/, null];
1147
+ case 4: return [2 /*return*/];
1148
+ }
1149
+ });
1150
+ });
1151
+ };
1152
+ SubscriptionManager.prototype.runPublicationLocally = function (sub, userId) {
1153
+ return __awaiter(this, void 0, void 0, function () {
1154
+ var pub, context, metadata, execution, _a;
1155
+ return __generator(this, function (_b) {
1156
+ switch (_b.label) {
1157
+ case 0:
1158
+ pub = this._publications[sub.publication];
1159
+ if (!pub) {
1160
+ throw new Error("Publication not found: ".concat(sub.publication));
1161
+ }
1162
+ context = Object.assign({}, this, SubscriptionManager.prototype);
1163
+ metadata = {
1164
+ publication: sub.publication,
1165
+ subscriptionData: sub.subscriptionData
1166
+ };
1167
+ if (!pub.user_specific) return [3 /*break*/, 2];
1168
+ return [4 /*yield*/, (0, subscription_dependency_context_1.withDependencyTracking)(function () {
1169
+ var _a;
1170
+ return (_a = pub.function).call.apply(_a, __spreadArray([context, userId || ''], __read(sub.subscriptionData), false));
1171
+ }, Object.assign({}, metadata, { userId: userId }))];
1172
+ case 1:
1173
+ _a = _b.sent();
1174
+ return [3 /*break*/, 4];
1175
+ case 2: return [4 /*yield*/, (0, subscription_dependency_context_1.withDependencyTracking)(function () {
1176
+ var _a;
1177
+ return (_a = pub.function).call.apply(_a, __spreadArray([context], __read(sub.subscriptionData), false));
1178
+ }, metadata)];
1179
+ case 3:
1180
+ _a = _b.sent();
1181
+ _b.label = 4;
1182
+ case 4:
1183
+ execution = _a;
1184
+ return [2 /*return*/, {
1185
+ result: execution.result,
1186
+ packedResult: this.packCachePayload(execution.result),
1187
+ snapshot: execution.snapshot,
1188
+ encoding: 'msgpack',
1189
+ workerUsed: false
1190
+ }];
1191
+ }
1192
+ });
1193
+ });
1194
+ };
1195
+ SubscriptionManager.prototype.runPublicationExecution = function (sub, userId) {
1196
+ return __awaiter(this, void 0, void 0, function () {
1197
+ var pub, effectiveUserId, workerExecution;
1198
+ return __generator(this, function (_a) {
1199
+ switch (_a.label) {
1200
+ case 0:
1201
+ pub = this._publications[sub.publication];
1202
+ if (!pub) {
1203
+ throw new Error("Publication not found: ".concat(sub.publication));
1204
+ }
1205
+ effectiveUserId = pub.user_specific ? userId : undefined;
1206
+ return [4 /*yield*/, this.runPublicationViaWorker(sub, effectiveUserId)];
1207
+ case 1:
1208
+ workerExecution = _a.sent();
1209
+ if (workerExecution) {
1210
+ return [2 /*return*/, workerExecution];
1211
+ }
1212
+ return [2 /*return*/, this.runPublicationLocally(sub, effectiveUserId)];
1213
+ }
1214
+ });
1215
+ });
1216
+ };
601
1217
  SubscriptionManager.prototype.sendDataToAllWithRetry = function (sub, collection, type) {
602
1218
  return __awaiter(this, void 0, void 0, function () {
603
1219
  return __generator(this, function (_a) {
@@ -668,6 +1284,12 @@ var SubscriptionManager = /** @class */ (function () {
668
1284
  SubscriptionManager.prototype.publications = function (method) {
669
1285
  this._publications = Object.assign(this._publications, method);
670
1286
  };
1287
+ SubscriptionManager.prototype.getPublication = function (publication) {
1288
+ return this._publications[publication];
1289
+ };
1290
+ SubscriptionManager.prototype.getPublications = function () {
1291
+ return this._publications;
1292
+ };
671
1293
  // Throttled `loggedInLatency` method
672
1294
  SubscriptionManager.prototype.loggedInLatency = function (ws) {
673
1295
  var _a, _b, _c, _d;
@@ -724,7 +1346,7 @@ var SubscriptionManager = /** @class */ (function () {
724
1346
  // Method to flush buffered latency updates in bulk
725
1347
  SubscriptionManager.prototype.flushThrottledLatencyUpdates = function () {
726
1348
  return __awaiter(this, void 0, void 0, function () {
727
- var pendingEntries, updates, error_1, pendingEntries_1, pendingEntries_1_1, _a, id_ws, payload, current;
1349
+ var pendingEntries, updates, error_4, pendingEntries_1, pendingEntries_1_1, _a, id_ws, payload, current;
728
1350
  var e_3, _b;
729
1351
  var _this = this;
730
1352
  return __generator(this, function (_c) {
@@ -759,7 +1381,7 @@ var SubscriptionManager = /** @class */ (function () {
759
1381
  }
760
1382
  return [3 /*break*/, 5];
761
1383
  case 3:
762
- error_1 = _c.sent();
1384
+ error_4 = _c.sent();
763
1385
  try {
764
1386
  for (pendingEntries_1 = __values(pendingEntries), pendingEntries_1_1 = pendingEntries_1.next(); !pendingEntries_1_1.done; pendingEntries_1_1 = pendingEntries_1.next()) {
765
1387
  _a = __read(pendingEntries_1_1.value, 2), id_ws = _a[0], payload = _a[1];
@@ -776,7 +1398,7 @@ var SubscriptionManager = /** @class */ (function () {
776
1398
  }
777
1399
  finally { if (e_3) throw e_3.error; }
778
1400
  }
779
- console.error(new Date(), 'Sub Manager', 'Throttled latency batch update failed', error_1);
1401
+ console.error(new Date(), 'Sub Manager', 'Throttled latency batch update failed', error_4);
780
1402
  return [3 /*break*/, 5];
781
1403
  case 4:
782
1404
  this._latencyFlushInProgress = false;
@@ -793,7 +1415,7 @@ var SubscriptionManager = /** @class */ (function () {
793
1415
  // Subscribe to publication
794
1416
  SubscriptionManager.prototype.subscribe = function (messageRoute, messageDate, ws, messageId, publication, subscriptionData) {
795
1417
  return __awaiter(this, void 0, void 0, function () {
796
- var pub, valObj, valKeys, rootKeys, i, staleRouteMessage, urlData, urlModule_1, urlNext, otherRouteSubs, normalizedSubscriptionData, subscriptionKey_1, sub;
1418
+ var pub, valObj, valKeys, rootKeys, i, staleRouteMessage, urlData, urlModule_1, urlNext, otherRouteSubs, normalizedSubscriptionData, subscriptionKey_1, sub, queued;
797
1419
  var _this = this;
798
1420
  return __generator(this, function (_a) {
799
1421
  switch (_a.label) {
@@ -906,6 +1528,19 @@ var SubscriptionManager = /** @class */ (function () {
906
1528
  if (this._enableDebug) {
907
1529
  console.log(new Date(), 'New Sub', sub.publication, sub.running, sub.runAgain, sub.clients.length);
908
1530
  }
1531
+ if (this.shouldQueueWarmup(publication, messageRoute)) {
1532
+ queued = this.queueWarmupSubscription({
1533
+ ws: ws,
1534
+ messageRoute: messageRoute,
1535
+ messageDate: messageDate,
1536
+ messageId: messageId,
1537
+ publication: publication,
1538
+ subscriptionData: normalizedSubscriptionData
1539
+ });
1540
+ if (queued) {
1541
+ return [2 /*return*/];
1542
+ }
1543
+ }
909
1544
  // Immediately send data to the new client
910
1545
  return [4 /*yield*/, this.processSubscription(sub, ws, messageId)];
911
1546
  case 2:
@@ -1058,6 +1693,18 @@ var SubscriptionManager = /** @class */ (function () {
1058
1693
  }
1059
1694
  return 0;
1060
1695
  };
1696
+ SubscriptionManager.prototype.parsePositiveFloat = function (value) {
1697
+ if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
1698
+ return value;
1699
+ }
1700
+ if (typeof value === 'string' && value.trim().length) {
1701
+ var parsed = parseFloat(value);
1702
+ if (Number.isFinite(parsed) && parsed > 0) {
1703
+ return parsed;
1704
+ }
1705
+ }
1706
+ return 0;
1707
+ };
1061
1708
  SubscriptionManager.prototype.isChangeStreamUnsupported = function (error) {
1062
1709
  var code = typeof (error === null || error === void 0 ? void 0 : error.code) === 'number' ? error.code : null;
1063
1710
  var codeName = typeof (error === null || error === void 0 ? void 0 : error.codeName) === 'string' ? error.codeName.toLowerCase() : '';
@@ -1177,7 +1824,7 @@ var SubscriptionManager = /** @class */ (function () {
1177
1824
  };
1178
1825
  SubscriptionManager.prototype.loadResumeToken = function () {
1179
1826
  return __awaiter(this, void 0, void 0, function () {
1180
- var db, doc, error_2;
1827
+ var db, doc, error_5;
1181
1828
  return __generator(this, function (_a) {
1182
1829
  switch (_a.label) {
1183
1830
  case 0:
@@ -1191,8 +1838,8 @@ var SubscriptionManager = /** @class */ (function () {
1191
1838
  doc = _a.sent();
1192
1839
  return [2 /*return*/, (doc === null || doc === void 0 ? void 0 : doc.token) || null];
1193
1840
  case 2:
1194
- error_2 = _a.sent();
1195
- console.log(new Date(), 'Sub Manager', 'Failed to load oplog resume token', error_2);
1841
+ error_5 = _a.sent();
1842
+ console.log(new Date(), 'Sub Manager', 'Failed to load oplog resume token', error_5);
1196
1843
  return [2 /*return*/, null];
1197
1844
  case 3: return [2 /*return*/];
1198
1845
  }
@@ -1201,7 +1848,7 @@ var SubscriptionManager = /** @class */ (function () {
1201
1848
  };
1202
1849
  SubscriptionManager.prototype.saveResumeToken = function (token) {
1203
1850
  return __awaiter(this, void 0, void 0, function () {
1204
- var db, error_3;
1851
+ var db, error_6;
1205
1852
  return __generator(this, function (_a) {
1206
1853
  switch (_a.label) {
1207
1854
  case 0:
@@ -1220,8 +1867,8 @@ var SubscriptionManager = /** @class */ (function () {
1220
1867
  _a.sent();
1221
1868
  return [3 /*break*/, 4];
1222
1869
  case 3:
1223
- error_3 = _a.sent();
1224
- console.log(new Date(), 'Sub Manager', 'Failed to persist oplog resume token', error_3);
1870
+ error_6 = _a.sent();
1871
+ console.log(new Date(), 'Sub Manager', 'Failed to persist oplog resume token', error_6);
1225
1872
  return [3 /*break*/, 4];
1226
1873
  case 4: return [2 /*return*/];
1227
1874
  }
@@ -1230,7 +1877,7 @@ var SubscriptionManager = /** @class */ (function () {
1230
1877
  };
1231
1878
  SubscriptionManager.prototype.clearResumeToken = function () {
1232
1879
  return __awaiter(this, void 0, void 0, function () {
1233
- var db, error_4;
1880
+ var db, error_7;
1234
1881
  return __generator(this, function (_a) {
1235
1882
  switch (_a.label) {
1236
1883
  case 0:
@@ -1244,8 +1891,8 @@ var SubscriptionManager = /** @class */ (function () {
1244
1891
  _a.sent();
1245
1892
  return [3 /*break*/, 3];
1246
1893
  case 2:
1247
- error_4 = _a.sent();
1248
- console.log(new Date(), 'Sub Manager', 'Failed to clear oplog resume token', error_4);
1894
+ error_7 = _a.sent();
1895
+ console.log(new Date(), 'Sub Manager', 'Failed to clear oplog resume token', error_7);
1249
1896
  return [3 /*break*/, 3];
1250
1897
  case 3: return [2 /*return*/];
1251
1898
  }
@@ -1316,7 +1963,7 @@ var SubscriptionManager = /** @class */ (function () {
1316
1963
  };
1317
1964
  SubscriptionManager.prototype.fullResyncSubscriptions = function (reason) {
1318
1965
  return __awaiter(this, void 0, void 0, function () {
1319
- var subs, subs_1, subs_1_1, sub, pub, _a, _b, client, ws, _c, e_4_1, e_5_1, error_5;
1966
+ var subs, subs_1, subs_1_1, sub, pub, _a, _b, client, ws, _c, e_4_1, e_5_1, error_8;
1320
1967
  var e_5, _d, e_4, _e;
1321
1968
  var _f, _g, _h, _j, _k;
1322
1969
  return __generator(this, function (_l) {
@@ -1414,8 +2061,8 @@ var SubscriptionManager = /** @class */ (function () {
1414
2061
  return [7 /*endfinally*/];
1415
2062
  case 19: return [3 /*break*/, 21];
1416
2063
  case 20:
1417
- error_5 = _l.sent();
1418
- console.log(new Date(), 'Sub Manager', 'Full resync failed', reason, error_5);
2064
+ error_8 = _l.sent();
2065
+ console.log(new Date(), 'Sub Manager', 'Full resync failed', reason, error_8);
1419
2066
  return [3 /*break*/, 21];
1420
2067
  case 21: return [2 /*return*/];
1421
2068
  }
@@ -1425,7 +2072,7 @@ var SubscriptionManager = /** @class */ (function () {
1425
2072
  // Watch (tail) Mongo's operation log on the entire database (all insert/modify/delete will trigger this function)
1426
2073
  SubscriptionManager.prototype.tailOpLog = function (resumeToken) {
1427
2074
  return __awaiter(this, void 0, void 0, function () {
1428
- var watchDatabases, pipeline, lastResumeToken_1, startedWithResumeToken, error_6, innerError_1, error_7;
2075
+ var watchDatabases, pipeline, lastResumeToken_1, startedWithResumeToken, error_9, innerError_1, error_10;
1429
2076
  var _this = this;
1430
2077
  return __generator(this, function (_a) {
1431
2078
  switch (_a.label) {
@@ -1486,9 +2133,9 @@ var SubscriptionManager = /** @class */ (function () {
1486
2133
  startedWithResumeToken = true;
1487
2134
  return [3 /*break*/, 16];
1488
2135
  case 5:
1489
- error_6 = _a.sent();
1490
- if (!this.isChangeStreamUnsupported(error_6)) return [3 /*break*/, 7];
1491
- return [4 /*yield*/, this.enableLocalOplogFallback('change-stream-unsupported', error_6)];
2136
+ error_9 = _a.sent();
2137
+ if (!this.isChangeStreamUnsupported(error_9)) return [3 /*break*/, 7];
2138
+ return [4 /*yield*/, this.enableLocalOplogFallback('change-stream-unsupported', error_9)];
1492
2139
  case 6:
1493
2140
  _a.sent();
1494
2141
  return [2 /*return*/];
@@ -1504,7 +2151,7 @@ var SubscriptionManager = /** @class */ (function () {
1504
2151
  case 10:
1505
2152
  _a.sent();
1506
2153
  lastResumeToken_1 = null;
1507
- console.log(new Date(), 'oplog resumeAfter failed, starting fresh', error_6);
2154
+ console.log(new Date(), 'oplog resumeAfter failed, starting fresh', error_9);
1508
2155
  _a.label = 11;
1509
2156
  case 11:
1510
2157
  _a.trys.push([11, 12, , 15]);
@@ -1528,13 +2175,13 @@ var SubscriptionManager = /** @class */ (function () {
1528
2175
  this._oplog$ = resolveio_server_app_1.ResolveIOServer.getMongoConnection().watch(pipeline, { fullDocument: 'updateLookup' });
1529
2176
  return [3 /*break*/, 21];
1530
2177
  case 18:
1531
- error_7 = _a.sent();
1532
- if (!this.isChangeStreamUnsupported(error_7)) return [3 /*break*/, 20];
1533
- return [4 /*yield*/, this.enableLocalOplogFallback('change-stream-unsupported', error_7)];
2178
+ error_10 = _a.sent();
2179
+ if (!this.isChangeStreamUnsupported(error_10)) return [3 /*break*/, 20];
2180
+ return [4 /*yield*/, this.enableLocalOplogFallback('change-stream-unsupported', error_10)];
1534
2181
  case 19:
1535
2182
  _a.sent();
1536
2183
  return [2 /*return*/];
1537
- case 20: throw error_7;
2184
+ case 20: throw error_10;
1538
2185
  case 21:
1539
2186
  console.log(new Date(), 'oplog started', startedWithResumeToken ? '(resumeAfter)' : '');
1540
2187
  this._oplog$.on('change', function (doc) { return __awaiter(_this, void 0, void 0, function () {
@@ -1784,7 +2431,7 @@ var SubscriptionManager = /** @class */ (function () {
1784
2431
  };
1785
2432
  SubscriptionManager.prototype.processSubscription = function (sub, ws, messageId) {
1786
2433
  return __awaiter(this, void 0, void 0, function () {
1787
- var cacheData, serverRes, _a;
2434
+ var cachedRaw, cachedBuffer, cacheData, serverRes, _a;
1788
2435
  return __generator(this, function (_b) {
1789
2436
  switch (_b.label) {
1790
2437
  case 0:
@@ -1793,19 +2440,29 @@ var SubscriptionManager = /** @class */ (function () {
1793
2440
  _b.label = 1;
1794
2441
  case 1:
1795
2442
  _b.trys.push([1, 2, , 4]);
1796
- cacheData = this.decodeCachePayload(this._nodeCache.get(sub.cacheId));
1797
- if (cacheData === null || cacheData === undefined) {
1798
- throw new Error('cache-miss');
2443
+ cachedRaw = this._nodeCache.get(sub.cacheId);
2444
+ cachedBuffer = this.getCacheBuffer(cachedRaw);
2445
+ if (cachedBuffer && cachedBuffer.byteLength) {
2446
+ if (this._enableDebug) {
2447
+ console.log(new Date(), 'Process Sub, Cache (packed)', sub.publication);
2448
+ }
2449
+ this._websocketManager.sendPackedBuffer(ws, messageId, false, cachedBuffer, 'msgpack');
1799
2450
  }
1800
- serverRes = {
1801
- messageId: messageId,
1802
- hasError: false,
1803
- data: cacheData
1804
- };
1805
- if (this._enableDebug) {
1806
- console.log(new Date(), 'Process Sub, Cache', sub.publication);
2451
+ else {
2452
+ cacheData = this.decodeCachePayload(cachedRaw);
2453
+ if (cacheData === null || cacheData === undefined) {
2454
+ throw new Error('cache-miss');
2455
+ }
2456
+ serverRes = {
2457
+ messageId: messageId,
2458
+ hasError: false,
2459
+ data: cacheData
2460
+ };
2461
+ if (this._enableDebug) {
2462
+ console.log(new Date(), 'Process Sub, Cache', sub.publication);
2463
+ }
2464
+ this.sendWS(ws, serverRes);
1807
2465
  }
1808
- this.sendWS(ws, serverRes);
1809
2466
  return [3 /*break*/, 4];
1810
2467
  case 2:
1811
2468
  _a = _b.sent();
@@ -1847,7 +2504,6 @@ var SubscriptionManager = /** @class */ (function () {
1847
2504
  SubscriptionManager.prototype.sendDataToOne = function (ws, messageId, sub, collection, type) {
1848
2505
  return __awaiter(this, void 0, void 0, function () {
1849
2506
  var startMs, monitor, dependencySnapshot, res, execution, serverRes, err_1, _a, normalizedError, correlationId, serverRes, errorPayload, durationMs;
1850
- var _this = this;
1851
2507
  var _b;
1852
2508
  return __generator(this, function (_c) {
1853
2509
  switch (_c.label) {
@@ -1858,24 +2514,23 @@ var SubscriptionManager = /** @class */ (function () {
1858
2514
  case 1:
1859
2515
  _c.trys.push([1, 3, 5, 7]);
1860
2516
  resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager().callMethod.call(resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager(), 'insertSubscriptionLog', type, sub.publication, collection, JSON.stringify(sub.subscriptionData));
1861
- return [4 /*yield*/, (0, subscription_dependency_context_1.withDependencyTracking)(function () {
1862
- var _a;
1863
- return (_a = _this._publications[sub.publication].function).call.apply(_a, __spreadArray([Object.assign({}, _this, SubscriptionManager.prototype), ws['id_user']], __read(sub.subscriptionData), false));
1864
- }, {
1865
- publication: sub.publication,
1866
- subscriptionData: sub.subscriptionData
1867
- })];
2517
+ return [4 /*yield*/, this.runPublicationExecution(sub, ws['id_user'])];
1868
2518
  case 2:
1869
2519
  execution = _c.sent();
1870
2520
  res = execution.result;
1871
2521
  dependencySnapshot = execution.snapshot;
1872
2522
  this.updateSubscriptionDependencies(sub, dependencySnapshot);
1873
- serverRes = {
1874
- messageId: messageId,
1875
- hasError: false,
1876
- data: res
1877
- };
1878
- this.sendWS(ws, serverRes);
2523
+ if (execution.packedResult) {
2524
+ this._websocketManager.sendPackedBuffer(ws, messageId, false, execution.packedResult, execution.encoding || 'msgpack');
2525
+ }
2526
+ else {
2527
+ serverRes = {
2528
+ messageId: messageId,
2529
+ hasError: false,
2530
+ data: res
2531
+ };
2532
+ this.sendWS(ws, serverRes);
2533
+ }
1879
2534
  return [3 /*break*/, 7];
1880
2535
  case 3:
1881
2536
  err_1 = _c.sent();
@@ -1948,10 +2603,9 @@ var SubscriptionManager = /** @class */ (function () {
1948
2603
  return __awaiter(this, void 0, void 0, function () {
1949
2604
  var subIndex, startMs, monitor, res, dependencySnapshot, execution, packedRes, shouldCache, cachedBuffer, isSame, _a, _b, client, ws, serverRes, _c, _d, client, ws, serverRes, nodeCacheSize, deleteCount, subArr, zz, err_2, _e, normalizedError, correlationId, _f, _g, client, ws, serverRes, errorPayload, durationMs;
1950
2605
  var e_6, _h, e_7, _j, e_8, _k;
1951
- var _this = this;
1952
- var _l;
1953
- return __generator(this, function (_m) {
1954
- switch (_m.label) {
2606
+ var _l, _m;
2607
+ return __generator(this, function (_o) {
2608
+ switch (_o.label) {
1955
2609
  case 0:
1956
2610
  if (!!sub.clients.length) return [3 /*break*/, 1];
1957
2611
  if (sub.cacheId) {
@@ -1968,25 +2622,19 @@ var SubscriptionManager = /** @class */ (function () {
1968
2622
  monitor = this._monitorManagerFunction.startMonitorFunction('Publication', sub.publication, '', '', sub.subscriptionData);
1969
2623
  res = void 0;
1970
2624
  dependencySnapshot = void 0;
1971
- _m.label = 2;
2625
+ _o.label = 2;
1972
2626
  case 2:
1973
- _m.trys.push([2, 4, 6, 8]);
2627
+ _o.trys.push([2, 4, 6, 8]);
1974
2628
  if (sub.publication !== 'superadminAPM' && sub.publication !== 'loggedInUsers') {
1975
2629
  resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager().callMethod.call(resolveio_server_app_1.ResolveIOServer.getMainServer().getMethodManager(), 'insertSubscriptionLog', type, sub.publication, collection, JSON.stringify(sub.subscriptionData));
1976
2630
  }
1977
- return [4 /*yield*/, (0, subscription_dependency_context_1.withDependencyTracking)(function () {
1978
- var _a;
1979
- return (_a = _this._publications[sub.publication].function).call.apply(_a, __spreadArray([Object.assign({}, _this, SubscriptionManager.prototype)], __read(sub.subscriptionData), false));
1980
- }, {
1981
- publication: sub.publication,
1982
- subscriptionData: sub.subscriptionData
1983
- })];
2631
+ return [4 /*yield*/, this.runPublicationExecution(sub)];
1984
2632
  case 3:
1985
- execution = _m.sent();
2633
+ execution = _o.sent();
1986
2634
  res = execution.result;
1987
2635
  dependencySnapshot = execution.snapshot;
1988
2636
  this.updateSubscriptionDependencies(sub, dependencySnapshot);
1989
- packedRes = this.packCachePayload(res);
2637
+ packedRes = (_l = execution.packedResult) !== null && _l !== void 0 ? _l : this.packCachePayload(res);
1990
2638
  shouldCache = this.shouldCachePayload(sub, packedRes);
1991
2639
  if (sub.cacheId) {
1992
2640
  cachedBuffer = this.getCacheBuffer(this._nodeCache.get(sub.cacheId));
@@ -1997,12 +2645,17 @@ var SubscriptionManager = /** @class */ (function () {
1997
2645
  client = _b.value;
1998
2646
  ws = this._websocketManager.getWebSocket(client.id_socket);
1999
2647
  if (ws && ws.readyState === ws.OPEN) {
2000
- serverRes = {
2001
- messageId: client.messageId,
2002
- hasError: false,
2003
- data: res
2004
- };
2005
- this.sendWS(ws, serverRes);
2648
+ if (packedRes) {
2649
+ this._websocketManager.sendPackedBuffer(ws, client.messageId, false, packedRes, execution.encoding || 'msgpack');
2650
+ }
2651
+ else {
2652
+ serverRes = {
2653
+ messageId: client.messageId,
2654
+ hasError: false,
2655
+ data: res
2656
+ };
2657
+ this.sendWS(ws, serverRes);
2658
+ }
2006
2659
  }
2007
2660
  }
2008
2661
  }
@@ -2035,12 +2688,17 @@ var SubscriptionManager = /** @class */ (function () {
2035
2688
  client = _d.value;
2036
2689
  ws = this._websocketManager.getWebSocket(client.id_socket);
2037
2690
  if (ws && ws.readyState === ws.OPEN) {
2038
- serverRes = {
2039
- messageId: client.messageId,
2040
- hasError: false,
2041
- data: res
2042
- };
2043
- this.sendWS(ws, serverRes);
2691
+ if (packedRes) {
2692
+ this._websocketManager.sendPackedBuffer(ws, client.messageId, false, packedRes, execution.encoding || 'msgpack');
2693
+ }
2694
+ else {
2695
+ serverRes = {
2696
+ messageId: client.messageId,
2697
+ hasError: false,
2698
+ data: res
2699
+ };
2700
+ this.sendWS(ws, serverRes);
2701
+ }
2044
2702
  }
2045
2703
  }
2046
2704
  }
@@ -2084,7 +2742,7 @@ var SubscriptionManager = /** @class */ (function () {
2084
2742
  }
2085
2743
  return [3 /*break*/, 8];
2086
2744
  case 4:
2087
- err_2 = _m.sent();
2745
+ err_2 = _o.sent();
2088
2746
  _e = (0, error_tracking_1.ensureErrorWithCorrelation)(err_2), normalizedError = _e.error, correlationId = _e.correlationId;
2089
2747
  try {
2090
2748
  for (_f = __values(sub.clients), _g = _f.next(); !_g.done; _g = _f.next()) {
@@ -2124,7 +2782,7 @@ var SubscriptionManager = /** @class */ (function () {
2124
2782
  return [4 /*yield*/, error_reporter_1.ErrorReporter.report({
2125
2783
  sourceApp: 'subscription-manager',
2126
2784
  message: 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'],
2127
- environment: (_l = this.serverConfig) === null || _l === void 0 ? void 0 : _l.ROOT_URL,
2785
+ environment: (_m = this.serverConfig) === null || _m === void 0 ? void 0 : _m.ROOT_URL,
2128
2786
  clientSlug: resolveio_server_app_1.ResolveIOServer.getClientName(),
2129
2787
  clientName: this.serverConfig['CLIENT_NAME'],
2130
2788
  stack: normalizedError === null || normalizedError === void 0 ? void 0 : normalizedError.stack,
@@ -2137,7 +2795,7 @@ var SubscriptionManager = /** @class */ (function () {
2137
2795
  correlationId: correlationId
2138
2796
  })];
2139
2797
  case 5:
2140
- _m.sent();
2798
+ _o.sent();
2141
2799
  return [3 /*break*/, 8];
2142
2800
  case 6:
2143
2801
  durationMs = Date.now() - startMs;
@@ -2155,7 +2813,7 @@ var SubscriptionManager = /** @class */ (function () {
2155
2813
  }
2156
2814
  return [4 /*yield*/, this._monitorManagerFunction.finishMonitorFunction(monitor)];
2157
2815
  case 7:
2158
- _m.sent();
2816
+ _o.sent();
2159
2817
  return [7 /*endfinally*/];
2160
2818
  case 8: return [2 /*return*/];
2161
2819
  }