@streamr/dht 103.6.0-rc.0 → 103.7.0-rc.2

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.
@@ -261,6 +261,65 @@ class SendFailed extends Err {
261
261
  constructor(message, originalError) { super(ErrorCode.SEND_FAILED, message, originalError); }
262
262
  }
263
263
 
264
+ let enabled = false;
265
+ function setGapDiagnosticsEnabled(val) {
266
+ enabled = val;
267
+ globalThis.__dhtGapDiagEnabled = val;
268
+ }
269
+ const SUMMARY_INTERVAL_MS = 2000;
270
+ const accumulators = new Map();
271
+ function logGapDiagnosticSampled(layer, opts = {}) {
272
+ if (!enabled)
273
+ return;
274
+ const now = performance.now();
275
+ const threshold = opts.outlierThresholdMs ?? 30;
276
+ let acc = accumulators.get(layer);
277
+ if (acc === undefined) {
278
+ acc = { count: 0, sumDeltaMs: 0, maxDeltaMs: 0, outlierCount: 0, lastReportMs: now, lastEventMs: now };
279
+ accumulators.set(layer, acc);
280
+ return;
281
+ }
282
+ const deltaMs = now - acc.lastEventMs;
283
+ acc.lastEventMs = now;
284
+ acc.count++;
285
+ if (deltaMs > acc.maxDeltaMs)
286
+ acc.maxDeltaMs = deltaMs;
287
+ acc.sumDeltaMs += deltaMs;
288
+ if (deltaMs > threshold)
289
+ acc.outlierCount++;
290
+ if (deltaMs > threshold) {
291
+ const payload = {
292
+ layer,
293
+ timestampMs: now,
294
+ deltaMs: +deltaMs.toFixed(2),
295
+ detail: opts.detail,
296
+ };
297
+ // eslint-disable-next-line no-console
298
+ console.log('[gap-diagnostics]', JSON.stringify(payload));
299
+ }
300
+ if (now - acc.lastReportMs >= SUMMARY_INTERVAL_MS) {
301
+ const summaryDetail = {
302
+ count: acc.count,
303
+ meanDeltaMs: acc.count > 0 ? +(acc.sumDeltaMs / acc.count).toFixed(2) : 0,
304
+ maxDeltaMs: +acc.maxDeltaMs.toFixed(2),
305
+ outlierCount: acc.outlierCount,
306
+ periodMs: +(now - acc.lastReportMs).toFixed(1),
307
+ };
308
+ const summary = {
309
+ layer: `${layer}.summary`,
310
+ timestampMs: now,
311
+ detail: summaryDetail,
312
+ };
313
+ // eslint-disable-next-line no-console
314
+ console.log('[gap-diagnostics]', JSON.stringify(summary));
315
+ acc.count = 0;
316
+ acc.sumDeltaMs = 0;
317
+ acc.maxDeltaMs = 0;
318
+ acc.outlierCount = 0;
319
+ acc.lastReportMs = now;
320
+ }
321
+ }
322
+
264
323
  // @generated message type with reflection information, may provide speed optimized methods
265
324
  class Empty$Type extends runtime.MessageType {
266
325
  constructor() {
@@ -2305,6 +2364,7 @@ class ConnectionManager extends eventemitter3.EventEmitter {
2305
2364
  if ((this.state === ConnectionManagerState.STOPPED || this.state === ConnectionManagerState.STOPPING) && !opts.sendIfStopped) {
2306
2365
  return;
2307
2366
  }
2367
+ logGapDiagnosticSampled('dht.connMgr.send');
2308
2368
  const peerDescriptor = message.targetDescriptor;
2309
2369
  if (this.isConnectionToSelf(peerDescriptor)) {
2310
2370
  throw new CannotConnectToSelf('Cannot send to self');
@@ -2380,6 +2440,7 @@ class ConnectionManager extends eventemitter3.EventEmitter {
2380
2440
  this.rpcCommunicator?.handleMessageFromPeer(message);
2381
2441
  }
2382
2442
  else {
2443
+ logGapDiagnosticSampled('dht.connMgr.emitMessage');
2383
2444
  logger$A.trace('emit "message" ' + toNodeId(message.sourceDescriptor)
2384
2445
  + ' ' + message.serviceId + ' ' + message.messageId);
2385
2446
  this.emit('message', message);
@@ -2389,6 +2450,7 @@ class ConnectionManager extends eventemitter3.EventEmitter {
2389
2450
  if (this.state === ConnectionManagerState.STOPPED) {
2390
2451
  return;
2391
2452
  }
2453
+ logGapDiagnosticSampled('dht.connMgr.onData');
2392
2454
  this.metrics.receiveBytesPerSecond.record(data.byteLength);
2393
2455
  this.metrics.receiveMessagesPerSecond.record(1);
2394
2456
  let message;
@@ -2822,7 +2884,7 @@ const parseVersion = (version) => {
2822
2884
  }
2823
2885
  };
2824
2886
 
2825
- var version = "103.6.0-rc.0";
2887
+ var version = "103.7.0-rc.2";
2826
2888
 
2827
2889
  const logger$y = new utils.Logger('Handshaker');
2828
2890
  // Optimally the Outgoing and Incoming Handshakers could be their own separate classes
@@ -3280,6 +3342,9 @@ class DirectWebrtcConnection extends eventemitter3.EventEmitter {
3280
3342
  }
3281
3343
  send(data) {
3282
3344
  if (this.lastState === 'connected') {
3345
+ logGapDiagnosticSampled('dht.dc.send', {
3346
+ detail: { bufferedAmount: this.dataChannel.bufferedAmount, queueLen: this.messageQueue.length }
3347
+ });
3283
3348
  if (this.dataChannel.bufferedAmount > this.bufferThresholdHigh) {
3284
3349
  this.messageQueue.push(data);
3285
3350
  }
@@ -3308,6 +3373,7 @@ class DirectWebrtcConnection extends eventemitter3.EventEmitter {
3308
3373
  };
3309
3374
  dataChannel.onmessage = (msg) => {
3310
3375
  logger$v.trace('dc.onmessage');
3376
+ logGapDiagnosticSampled('dht.dc.onmessage');
3311
3377
  this.emit('data', new Uint8Array(msg.data));
3312
3378
  };
3313
3379
  dataChannel.onbufferedamountlow = () => {
@@ -3602,7 +3668,7 @@ class WorkerWebrtcConnection extends eventemitter3.EventEmitter {
3602
3668
  if (state === DisconnectedState.CLOSED ||
3603
3669
  state === DisconnectedState.DISCONNECTED ||
3604
3670
  state === DisconnectedState.FAILED) {
3605
- this.doClose(false);
3671
+ this.doClose(false, `pcState=${state}`);
3606
3672
  }
3607
3673
  },
3608
3674
  onDataChannel: (channel) => {
@@ -3655,6 +3721,9 @@ class WorkerWebrtcConnection extends eventemitter3.EventEmitter {
3655
3721
  }
3656
3722
  send(data) {
3657
3723
  if (this.connected && this.dataChannel) {
3724
+ logGapDiagnosticSampled('dht.dc.send', {
3725
+ detail: { bufferedAmount: this.dataChannel.bufferedAmount, queueLen: this.messageQueue.length }
3726
+ });
3658
3727
  if (this.dataChannel.bufferedAmount > this.bufferThresholdHigh) {
3659
3728
  this.messageQueue.push(data);
3660
3729
  }
@@ -3684,13 +3753,14 @@ class WorkerWebrtcConnection extends eventemitter3.EventEmitter {
3684
3753
  };
3685
3754
  dataChannel.onclose = () => {
3686
3755
  logger$u.trace('dc.onClosed (worker)');
3687
- this.doClose(false);
3756
+ this.doClose(false, 'dataChannel.onclose');
3688
3757
  };
3689
3758
  dataChannel.onerror = (err) => {
3690
3759
  logger$u.warn('Data channel error (worker)', { err });
3691
3760
  };
3692
3761
  dataChannel.onmessage = (msg) => {
3693
3762
  logger$u.trace('dc.onmessage (worker)');
3763
+ logGapDiagnosticSampled('dht.dc.onmessage');
3694
3764
  this.emit('data', new Uint8Array(msg.data));
3695
3765
  };
3696
3766
  dataChannel.onbufferedamountlow = () => {
@@ -5960,7 +6030,7 @@ class PeerDiscovery {
5960
6030
  logger$d.debug(`Ring join on ${this.options.serviceId} timed out`);
5961
6031
  }
5962
6032
  finally {
5963
- sessions.forEach((session) => this.ongoingDiscoverySessions.delete(session.id));
6033
+ sessions.forEach((session) => this.ongoingRingDiscoverySessions.delete(session.id));
5964
6034
  }
5965
6035
  }
5966
6036
  async rejoinDht(entryPoint, contactedPeers = new Set(), distantJoinContactPeers = new Set()) {
@@ -8078,7 +8148,9 @@ exports.createOutgoingHandshaker = createOutgoingHandshaker;
8078
8148
  exports.getRandomRegion = getRandomRegion;
8079
8149
  exports.getRegionDelayMatrix = getRegionDelayMatrix;
8080
8150
  exports.installWebrtcBridge = installWebrtcBridge;
8151
+ exports.logGapDiagnosticSampled = logGapDiagnosticSampled;
8081
8152
  exports.randomDhtAddress = randomDhtAddress;
8153
+ exports.setGapDiagnosticsEnabled = setGapDiagnosticsEnabled;
8082
8154
  exports.toDhtAddress = toDhtAddress;
8083
8155
  exports.toDhtAddressRaw = toDhtAddressRaw;
8084
8156
  exports.toNodeId = toNodeId;