@streamr/trackerless-network 103.6.0-rc.0 → 103.8.0-rc.3

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/dist/exports.cjs CHANGED
@@ -29,7 +29,7 @@ class ExternalNetworkRpc {
29
29
  }
30
30
  }
31
31
 
32
- var version = "103.6.0-rc.0";
32
+ var version = "103.8.0-rc.3";
33
33
 
34
34
  // @generated message type with reflection information, may provide speed optimized methods
35
35
  class Any$Type extends runtime.MessageType {
@@ -2404,12 +2404,72 @@ class NeighborUpdateManager {
2404
2404
  }
2405
2405
  }
2406
2406
 
2407
+ let enabled = false;
2408
+ function setGapDiagnosticsEnabled(val) {
2409
+ enabled = val;
2410
+ globalThis.__trackerlessGapDiagEnabled = val;
2411
+ }
2412
+ const SUMMARY_INTERVAL_MS = 2000;
2413
+ const accumulators = new Map();
2414
+ function logGapDiagnosticSampled(layer, opts = {}) {
2415
+ if (!enabled)
2416
+ return;
2417
+ const now = performance.now();
2418
+ const threshold = opts.outlierThresholdMs ?? 30;
2419
+ let acc = accumulators.get(layer);
2420
+ if (acc === undefined) {
2421
+ acc = { count: 0, sumDeltaMs: 0, maxDeltaMs: 0, outlierCount: 0, lastReportMs: now, lastEventMs: now };
2422
+ accumulators.set(layer, acc);
2423
+ return;
2424
+ }
2425
+ const deltaMs = now - acc.lastEventMs;
2426
+ acc.lastEventMs = now;
2427
+ acc.count++;
2428
+ if (deltaMs > acc.maxDeltaMs)
2429
+ acc.maxDeltaMs = deltaMs;
2430
+ acc.sumDeltaMs += deltaMs;
2431
+ if (deltaMs > threshold)
2432
+ acc.outlierCount++;
2433
+ if (deltaMs > threshold) {
2434
+ const payload = {
2435
+ layer,
2436
+ timestampMs: now,
2437
+ deltaMs: +deltaMs.toFixed(2),
2438
+ detail: opts.detail,
2439
+ };
2440
+ // eslint-disable-next-line no-console
2441
+ console.log('[gap-diagnostics]', JSON.stringify(payload));
2442
+ }
2443
+ if (now - acc.lastReportMs >= SUMMARY_INTERVAL_MS) {
2444
+ const summaryDetail = {
2445
+ count: acc.count,
2446
+ meanDeltaMs: acc.count > 0 ? +(acc.sumDeltaMs / acc.count).toFixed(2) : 0,
2447
+ maxDeltaMs: +acc.maxDeltaMs.toFixed(2),
2448
+ outlierCount: acc.outlierCount,
2449
+ periodMs: +(now - acc.lastReportMs).toFixed(1),
2450
+ };
2451
+ const summary = {
2452
+ layer: `${layer}.summary`,
2453
+ timestampMs: now,
2454
+ detail: summaryDetail,
2455
+ };
2456
+ // eslint-disable-next-line no-console
2457
+ console.log('[gap-diagnostics]', JSON.stringify(summary));
2458
+ acc.count = 0;
2459
+ acc.sumDeltaMs = 0;
2460
+ acc.maxDeltaMs = 0;
2461
+ acc.outlierCount = 0;
2462
+ acc.lastReportMs = now;
2463
+ }
2464
+ }
2465
+
2407
2466
  class ContentDeliveryRpcLocal {
2408
2467
  options;
2409
2468
  constructor(options) {
2410
2469
  this.options = options;
2411
2470
  }
2412
2471
  async sendStreamMessage(message, context) {
2472
+ logGapDiagnosticSampled('trackerless.rpcLocal.sendStreamMessage');
2413
2473
  const previousNode = context.incomingSourceDescriptor;
2414
2474
  const previousNodeId = dht.toNodeId(previousNode);
2415
2475
  this.options.markForInspection(previousNodeId, message.messageId);
@@ -2770,12 +2830,23 @@ class ContentDeliveryLayerNode extends eventemitter3.EventEmitter {
2770
2830
  this.options.neighborFinder.stop();
2771
2831
  this.options.neighborUpdateManager.stop();
2772
2832
  this.options.inspector.stop();
2833
+ this.duplicateDetectors.clear();
2773
2834
  }
2774
2835
  broadcast(msg, previousNode) {
2775
2836
  if (!previousNode) {
2837
+ logGapDiagnosticSampled('trackerless.cdNode.broadcastOut');
2776
2838
  markAndCheckDuplicate(this.duplicateDetectors, msg.messageId, msg.previousMessageRef);
2777
2839
  }
2778
- this.emit('message', msg);
2840
+ else {
2841
+ logGapDiagnosticSampled('trackerless.cdNode.broadcastIn');
2842
+ }
2843
+ // Deliver to local listeners — except own publishes (no previousNode)
2844
+ // when loopback is suppressed: nothing local consumes them and they
2845
+ // would otherwise be re-serialized across a worker boundary just to be
2846
+ // discarded. Propagation + duplicate detection below are unaffected.
2847
+ if (previousNode !== undefined || !this.options.suppressOwnMessageLoopback) {
2848
+ this.emit('message', msg);
2849
+ }
2779
2850
  const skipBackPropagation = previousNode !== undefined && !this.options.temporaryConnectionRpcLocal.hasNode(previousNode);
2780
2851
  this.options.propagation.feedUnseenMessage(msg, this.getPropagationTargets(msg), skipBackPropagation ? previousNode : null);
2781
2852
  this.messagesPropagated += 1;
@@ -3072,6 +3143,7 @@ class Propagation {
3072
3143
  }
3073
3144
  sendAndAwaitThenMark({ message, source, handledNeighbors }, neighborId) {
3074
3145
  if (!handledNeighbors.has(neighborId) && neighborId !== source) {
3146
+ logGapDiagnosticSampled('trackerless.propagation.sendToNeighbor');
3075
3147
  (async () => {
3076
3148
  try {
3077
3149
  await this.sendToNeighbor(neighborId, message);
@@ -3629,6 +3701,9 @@ class PlumtreeManager extends eventemitter3.EventEmitter {
3629
3701
  stop() {
3630
3702
  this.abortController.abort();
3631
3703
  this.neighbors.off('nodeRemoved', this.onNeighborRemoved);
3704
+ this.latestMessages.clear();
3705
+ this.recoveryState.clear();
3706
+ this.recoveryCooldownUntil.clear();
3632
3707
  }
3633
3708
  }
3634
3709
 
@@ -4151,6 +4226,7 @@ class ContentDeliveryManager extends eventemitter3.EventEmitter {
4151
4226
  neighborUpdateInterval: this.options.neighborUpdateInterval,
4152
4227
  isLocalNodeEntryPoint,
4153
4228
  bufferWhileConnecting: this.options.bufferWhileConnecting,
4229
+ suppressOwnMessageLoopback: this.options.suppressOwnMessageLoopback,
4154
4230
  plumtreeOptimization: streamPartDeliveryOptions?.plumtreeOptimization?.enabled,
4155
4231
  plumtreeMaxPausedNeighbors: streamPartDeliveryOptions?.plumtreeOptimization?.enabled === true ?
4156
4232
  streamPartDeliveryOptions?.plumtreeOptimization?.maxPausedNeighbors : undefined
@@ -4580,5 +4656,7 @@ exports.NetworkNode = NetworkNode;
4580
4656
  exports.NetworkStack = NetworkStack;
4581
4657
  exports.StreamMessage = StreamMessage;
4582
4658
  exports.createNetworkNode = createNetworkNode;
4659
+ exports.logGapDiagnosticSampled = logGapDiagnosticSampled;
4660
+ exports.setTrackerlessGapDiagnosticsEnabled = setGapDiagnosticsEnabled;
4583
4661
  exports.streamPartIdToDataKey = streamPartIdToDataKey;
4584
4662
  //# sourceMappingURL=exports.cjs.map