@peerbit/pubsub 5.4.9 → 5.4.12

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.
@@ -371,7 +371,7 @@ export type FanoutTreeJoinOptions = {
371
371
  */
372
372
  parentUpgradeStaleRootProbeProbability?: number;
373
373
  /**
374
- * How long to wait for a parent probe reply before skipping that candidate.
374
+ * How long to wait for a candidate or idle-parent probe reply.
375
375
  */
376
376
  parentProbeTimeoutMs?: number;
377
377
  /**
@@ -525,6 +525,11 @@ export interface FanoutTreeEvents extends StreamEvents {
525
525
  root: string;
526
526
  parent: string;
527
527
  }>;
528
+ "fanout:child-joined": CustomEvent<{
529
+ topic: string;
530
+ root: string;
531
+ child: string;
532
+ }>;
528
533
  "fanout:kicked": CustomEvent<{
529
534
  topic: string;
530
535
  root: string;
@@ -544,6 +549,7 @@ export declare class FanoutTree extends DirectStream<FanoutTreeEvents> {
544
549
  private channelsBySuffixKey;
545
550
  private readonly cachedSuffixKey;
546
551
  private readonly metricsBySuffixKey;
552
+ private readonly providerControlMetrics;
547
553
  private readonly joinTimeoutStreakByPeer;
548
554
  private readonly joinResetCooldownUntilByPeer;
549
555
  private bootstraps;
@@ -566,6 +572,8 @@ export declare class FanoutTree extends DirectStream<FanoutTreeEvents> {
566
572
  private readonly nativeFanout?;
567
573
  private readonly codec;
568
574
  constructor(components: DirectStreamComponents, opts?: FanoutTreeStreamOptions);
575
+ private registerUnderlayPeerDisconnectHandler;
576
+ start(): Promise<void>;
569
577
  private createLoopCloseController;
570
578
  stop(): Promise<void>;
571
579
  setBootstraps(addrs: Array<string | Multiaddr>): void;
@@ -574,6 +582,7 @@ export declare class FanoutTree extends DirectStream<FanoutTreeEvents> {
574
582
  private pruneTrackerNamespaceIfEmpty;
575
583
  private touchProviderNamespace;
576
584
  private pruneProviderNamespaceIfEmpty;
585
+ private touchProviderWatchers;
577
586
  private pruneProviderWatchersIfEmpty;
578
587
  private getProviderCandidatesFromCache;
579
588
  /** Decoded provider entries (raw multiaddr bytes) -> candidates. Invalid
@@ -710,6 +719,8 @@ export declare class FanoutTree extends DirectStream<FanoutTreeEvents> {
710
719
  private makeDataId;
711
720
  private getSuffixKeyFromId;
712
721
  private getMetricsForSuffixKey;
722
+ private storeDetachedMetrics;
723
+ private getControlMetrics;
713
724
  private recordControlSend;
714
725
  private recordControlReceive;
715
726
  private markCached;
@@ -721,6 +732,7 @@ export declare class FanoutTree extends DirectStream<FanoutTreeEvents> {
721
732
  private refillUploadTokens;
722
733
  private refillNeighborRepairTokens;
723
734
  private takeIngressBudget;
735
+ private setIngressBucket;
724
736
  private _sendData;
725
737
  private _forwardDataMessage;
726
738
  private noteReceivedSeq;
@@ -1 +1 @@
1
- {"version":3,"file":"fanout-tree.d.ts","sourceRoot":"","sources":["../../src/fanout-tree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fanout-tree.d.ts","sourceRoot":"","sources":["../../src/fanout-tree.ts"],"names":[],"mappings":"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"}
@@ -32,6 +32,19 @@ const PROVIDER_DIRECTORY_MAX_NAMESPACES = 4_096;
32
32
  // large networks can cause unbounded memory growth on the tracker nodes.
33
33
  const TRACKER_DIRECTORY_MAX_ENTRIES = 16_384;
34
34
  const TRACKER_DIRECTORY_MAX_NAMESPACES = 4_096;
35
+ // Best-effort bound on per-key control metrics for keys without an open channel.
36
+ // Every inbound control frame is recorded under its key, including tracker frames
37
+ // for channels we do not host, so bootstraps/relays see an open-ended key set.
38
+ // Open channels keep their metrics on the channel and are never evicted.
39
+ const DETACHED_METRICS_MAX_KEYS = 4_096;
40
+ // Best-effort bounds for provider watches and namespace names. Provider namespaces
41
+ // are commonly per block (`cid:<cid>`), so anything keyed by them must be bounded.
42
+ const PROVIDER_WATCH_MAX_NAMESPACES = 4_096;
43
+ const PROVIDER_NAMESPACE_NAME_MAX_ENTRIES = 16_384;
44
+ // Per-channel ingress token buckets (proxy-publish/unicast) are kept for recent
45
+ // senders only: a few multiples of the child limit, with a small floor.
46
+ const INGRESS_BUCKETS_MIN_ENTRIES = 64;
47
+ const INGRESS_BUCKETS_PER_CHILD = 4;
35
48
  const FANOUT_PROTOCOLS = ["/peerbit/fanout-tree/0.5.0"];
36
49
  const ID_PREFIX = Uint8Array.from([0x46, 0x4f, 0x55, 0x54]); // "FOUT"
37
50
  const OVERLOAD_KICK_STREAK_THRESHOLD = 5;
@@ -44,6 +57,7 @@ const DATA_WRITE_FAIL_KICK_COOLDOWN_MS = 2_000;
44
57
  const DATA_WRITE_FAIL_KICK_MAX_PER_EVENT = 4;
45
58
  const PARENT_REPAIR_DEAD_STREAK_THRESHOLD = 16;
46
59
  const PARENT_REPAIR_DEAD_MIN_LIVENESS_MS = 15_000;
60
+ const PARENT_IDLE_PROBE_INTERVAL_MS = 5_000;
47
61
  const REPAIR_RETRY_MIN_MS = 1_000;
48
62
  const REPAIR_RETRY_INTERVAL_FACTOR = 5;
49
63
  // A stream can remain locally readable/writable while silently dropping every
@@ -135,6 +149,7 @@ const createEmptyMetrics = () => ({
135
149
  reparentUpgradeSkipProbeOverloaded: 0,
136
150
  reparentUpgradeSkipProbeCooldown: 0,
137
151
  parentProbeReqSent: 0,
152
+ parentHealthProbeReqSent: 0,
138
153
  parentProbeReqReceived: 0,
139
154
  parentProbeReplySent: 0,
140
155
  parentProbeReplyReceived: 0,
@@ -190,10 +205,21 @@ const isDataId = (id) => id.length === 32 &&
190
205
  id[1] === ID_PREFIX[1] &&
191
206
  id[2] === ID_PREFIX[2] &&
192
207
  id[3] === ID_PREFIX[3];
208
+ const isProviderControlKind = (kind) => kind === MSG_PROVIDER_ANNOUNCE ||
209
+ kind === MSG_PROVIDER_QUERY ||
210
+ kind === MSG_PROVIDER_REPLY ||
211
+ kind === MSG_PROVIDER_SUBSCRIBE ||
212
+ kind === MSG_PROVIDER_UNSUBSCRIBE ||
213
+ kind === MSG_PROVIDER_NOTIFY;
193
214
  export class FanoutTree extends DirectStream {
194
215
  channelsBySuffixKey = new Map();
195
216
  cachedSuffixKey = new WeakMap();
217
+ // Metrics for keys without an open channel, in LRU order (oldest first) and
218
+ // bounded by DETACHED_METRICS_MAX_KEYS. Open channels own `ch.metrics`.
196
219
  metricsBySuffixKey = new Map();
220
+ // Provider control frames are keyed per provider namespace (often per block),
221
+ // which no channel metrics lookup can address, so they share one aggregate.
222
+ providerControlMetrics = createEmptyMetrics();
197
223
  joinTimeoutStreakByPeer = new Map();
198
224
  joinResetCooldownUntilByPeer = new Map();
199
225
  bootstraps = [];
@@ -234,6 +260,11 @@ export class FanoutTree extends DirectStream {
234
260
  this.unicastAckNodeTag32 = readU32BE(sha256Sync(textEncoder.encode(this.publicKeyHash)), 0);
235
261
  this.topicRootControlPlane =
236
262
  topicRootControlPlane ?? new TopicRootControlPlane();
263
+ this.registerUnderlayPeerDisconnectHandler();
264
+ }
265
+ registerUnderlayPeerDisconnectHandler() {
266
+ if (this.underlayPeerDisconnectHandler)
267
+ return;
237
268
  const onPeerDisconnect = (ev) => {
238
269
  const peerId = ev?.detail;
239
270
  if (!peerId)
@@ -250,6 +281,14 @@ export class FanoutTree extends DirectStream {
250
281
  this.underlayPeerDisconnectHandler = onPeerDisconnect;
251
282
  this.components.events.addEventListener("peer:disconnect", onPeerDisconnect);
252
283
  }
284
+ async start() {
285
+ await super.start();
286
+ // stop() removes the listener, so a restarted instance must add it again
287
+ // (but not while a stop that raced this start is still tearing down).
288
+ if (this.started && !this.stopping) {
289
+ this.registerUnderlayPeerDisconnectHandler();
290
+ }
291
+ }
253
292
  createLoopCloseController() {
254
293
  const controller = new AbortController();
255
294
  const stopSignal = this.closeController.signal;
@@ -341,6 +380,20 @@ export class FanoutTree extends DirectStream {
341
380
  this.pendingProviderQueryBySuffixKey.delete(suffixKey);
342
381
  }
343
382
  }
383
+ touchProviderWatchers(suffixKey) {
384
+ // LRU touch
385
+ const watchers = this.providerWatchersBySuffixKey.get(suffixKey) ??
386
+ new Map();
387
+ this.providerWatchersBySuffixKey.delete(suffixKey);
388
+ this.providerWatchersBySuffixKey.set(suffixKey, watchers);
389
+ while (this.providerWatchersBySuffixKey.size > PROVIDER_WATCH_MAX_NAMESPACES) {
390
+ const oldest = this.providerWatchersBySuffixKey.keys().next().value;
391
+ if (oldest === undefined)
392
+ break;
393
+ this.providerWatchersBySuffixKey.delete(oldest);
394
+ }
395
+ return watchers;
396
+ }
344
397
  pruneProviderWatchersIfEmpty(suffixKey) {
345
398
  const watchers = this.providerWatchersBySuffixKey.get(suffixKey);
346
399
  if (watchers && watchers.size === 0) {
@@ -465,7 +518,16 @@ export class FanoutTree extends DirectStream {
465
518
  getProviderNamespaceId(namespace) {
466
519
  const key = sha256Sync(textEncoder.encode(`provider|${namespace}`));
467
520
  const suffixKey = toBase64(key.subarray(0, 24));
521
+ // LRU touch: every announced block adds a namespace, so keep this bounded.
522
+ this.providerNamespaceBySuffixKey.delete(suffixKey);
468
523
  this.providerNamespaceBySuffixKey.set(suffixKey, namespace);
524
+ while (this.providerNamespaceBySuffixKey.size >
525
+ PROVIDER_NAMESPACE_NAME_MAX_ENTRIES) {
526
+ const oldest = this.providerNamespaceBySuffixKey.keys().next().value;
527
+ if (oldest === undefined)
528
+ break;
529
+ this.providerNamespaceBySuffixKey.delete(oldest);
530
+ }
469
531
  return { namespace, key, suffixKey };
470
532
  }
471
533
  getProviderNamespaceIdFromKey(key, suffixKey = toBase64(key.subarray(0, 24))) {
@@ -1037,6 +1099,9 @@ export class FanoutTree extends DirectStream {
1037
1099
  lastTrackerQueryAt: 0,
1038
1100
  };
1039
1101
  this.channelsBySuffixKey.set(id.suffixKey, ch);
1102
+ // The open channel now owns its metrics; take them out of the detached LRU
1103
+ // so they can never be evicted while the channel is open.
1104
+ this.metricsBySuffixKey.delete(id.suffixKey);
1040
1105
  const needsAnnounceLoop = ch.effectiveMaxChildren > 0;
1041
1106
  if (needsAnnounceLoop) {
1042
1107
  ch.announceLoop = this._announceLoop(ch).catch(() => { });
@@ -1204,6 +1269,12 @@ export class FanoutTree extends DirectStream {
1204
1269
  if (!peerHash)
1205
1270
  return;
1206
1271
  this.joinTimeoutStreakByPeer.delete(peerHash);
1272
+ // A disconnected watcher can no longer receive provider notifications.
1273
+ for (const [suffixKey, watchers] of this.providerWatchersBySuffixKey) {
1274
+ if (watchers.delete(peerHash) && watchers.size === 0) {
1275
+ this.providerWatchersBySuffixKey.delete(suffixKey);
1276
+ }
1277
+ }
1207
1278
  // Detach from a disconnected parent immediately, so children can rejoin.
1208
1279
  // This is more reliable than polling `getConnections()` because the underlay
1209
1280
  // can flap/reconnect faster than the join loop cadence.
@@ -1286,6 +1357,8 @@ export class FanoutTree extends DirectStream {
1286
1357
  ch.routeByPeer.clear();
1287
1358
  this.channelsBySuffixKey.delete(id.suffixKey);
1288
1359
  this.trackerBySuffixKey.delete(id.suffixKey);
1360
+ // Keep the counters readable after close (and across a reopen), bounded.
1361
+ this.storeDetachedMetrics(id.suffixKey, ch.metrics);
1289
1362
  await Promise.all(pendingSends);
1290
1363
  }
1291
1364
  getChannelStats(topic, root) {
@@ -2265,21 +2338,45 @@ export class FanoutTree extends DirectStream {
2265
2338
  return key;
2266
2339
  }
2267
2340
  getMetricsForSuffixKey(suffixKey) {
2268
- let m = this.metricsBySuffixKey.get(suffixKey);
2269
- if (!m) {
2270
- m = createEmptyMetrics();
2271
- this.metricsBySuffixKey.set(suffixKey, m);
2272
- }
2341
+ const ch = this.channelsBySuffixKey.get(suffixKey);
2342
+ if (ch)
2343
+ return ch.metrics;
2344
+ const m = this.metricsBySuffixKey.get(suffixKey) ?? createEmptyMetrics();
2345
+ this.storeDetachedMetrics(suffixKey, m);
2273
2346
  return m;
2274
2347
  }
2275
- recordControlSend(bytes, transmissions) {
2348
+ storeDetachedMetrics(suffixKey, metrics) {
2349
+ // LRU touch
2350
+ this.metricsBySuffixKey.delete(suffixKey);
2351
+ this.metricsBySuffixKey.set(suffixKey, metrics);
2352
+ while (this.metricsBySuffixKey.size > DETACHED_METRICS_MAX_KEYS) {
2353
+ const oldest = this.metricsBySuffixKey.keys().next().value;
2354
+ if (oldest === undefined)
2355
+ break;
2356
+ this.metricsBySuffixKey.delete(oldest);
2357
+ }
2358
+ }
2359
+ getControlMetrics(suffixKey, kind) {
2360
+ return isProviderControlKind(kind)
2361
+ ? this.providerControlMetrics
2362
+ : this.getMetricsForSuffixKey(suffixKey);
2363
+ }
2364
+ /**
2365
+ * Returns aggregate diagnostic counters for provider control frames.
2366
+ *
2367
+ * @internal
2368
+ */
2369
+ getProviderControlMetrics() {
2370
+ return this.providerControlMetrics;
2371
+ }
2372
+ recordControlSend(bytes, transmissions, probePurpose = "upgrade") {
2276
2373
  if (transmissions <= 0)
2277
2374
  return;
2278
2375
  if (bytes.length < 1 + 24)
2279
2376
  return;
2280
2377
  const kind = bytes[0];
2281
2378
  const suffixKey = toBase64(bytes.subarray(1, 25));
2282
- const m = this.getMetricsForSuffixKey(suffixKey);
2379
+ const m = this.getControlMetrics(suffixKey, kind);
2283
2380
  m.controlSends += transmissions;
2284
2381
  const sentBytes = bytes.byteLength * transmissions;
2285
2382
  m.controlBytesSent += sentBytes;
@@ -2334,6 +2431,9 @@ export class FanoutTree extends DirectStream {
2334
2431
  break;
2335
2432
  case MSG_PARENT_PROBE_REQ:
2336
2433
  m.parentProbeReqSent += transmissions;
2434
+ if (probePurpose === "health") {
2435
+ m.parentHealthProbeReqSent += transmissions;
2436
+ }
2337
2437
  m.controlBytesSentJoin += sentBytes;
2338
2438
  break;
2339
2439
  case MSG_PARENT_PROBE_REPLY:
@@ -2353,7 +2453,7 @@ export class FanoutTree extends DirectStream {
2353
2453
  }
2354
2454
  }
2355
2455
  recordControlReceive(suffixKey, kind, bytesReceived) {
2356
- const m = this.getMetricsForSuffixKey(suffixKey);
2456
+ const m = this.getControlMetrics(suffixKey, kind);
2357
2457
  m.controlReceives += 1;
2358
2458
  m.controlBytesReceived += bytesReceived;
2359
2459
  switch (kind) {
@@ -2473,14 +2573,14 @@ export class FanoutTree extends DirectStream {
2473
2573
  // Best-effort reset. The join loop keeps retrying other candidates.
2474
2574
  }
2475
2575
  }
2476
- async _sendControl(to, bytes, signal) {
2576
+ async _sendControl(to, bytes, signal, probePurpose = "upgrade") {
2477
2577
  if (signal?.aborted) {
2478
2578
  throw signal.reason ?? new AbortError("fanout control send aborted");
2479
2579
  }
2480
2580
  const stream = this.peers.get(to);
2481
2581
  if (!stream)
2482
2582
  return;
2483
- this.recordControlSend(bytes, 1);
2583
+ this.recordControlSend(bytes, 1, probePurpose);
2484
2584
  const message = await this.createMessage(bytes, {
2485
2585
  mode: new AnyWhere(),
2486
2586
  priority: CONTROL_PRIORITY,
@@ -2550,16 +2650,26 @@ export class FanoutTree extends DirectStream {
2550
2650
  tokens = Math.min(capacity, tokens + (elapsedMs * budgetBps) / 1_000);
2551
2651
  }
2552
2652
  if (tokens < costBytes) {
2553
- // LRU-touch on access to keep the bucket map bounded by active children.
2554
- byPeer.delete(fromHash);
2555
- byPeer.set(fromHash, { tokens, lastRefillAt: now });
2653
+ this.setIngressBucket(ch, byPeer, fromHash, { tokens, lastRefillAt: now });
2556
2654
  return false;
2557
2655
  }
2558
2656
  tokens -= costBytes;
2559
- byPeer.delete(fromHash);
2560
- byPeer.set(fromHash, { tokens, lastRefillAt: now });
2657
+ this.setIngressBucket(ch, byPeer, fromHash, { tokens, lastRefillAt: now });
2561
2658
  return true;
2562
2659
  }
2660
+ setIngressBucket(ch, byPeer, fromHash, bucket) {
2661
+ // LRU touch, capped: long-lived (pinned) roots see an open-ended set of
2662
+ // children over time, and buckets are not dropped when a child leaves.
2663
+ byPeer.delete(fromHash);
2664
+ byPeer.set(fromHash, bucket);
2665
+ const maxBuckets = Math.max(INGRESS_BUCKETS_MIN_ENTRIES, ch.maxChildren * INGRESS_BUCKETS_PER_CHILD);
2666
+ while (byPeer.size > maxBuckets) {
2667
+ const oldest = byPeer.keys().next().value;
2668
+ if (oldest === undefined)
2669
+ break;
2670
+ byPeer.delete(oldest);
2671
+ }
2672
+ }
2563
2673
  async _sendData(ch, to, seq, payload) {
2564
2674
  this.markCached(ch, seq, payload);
2565
2675
  ch.maxSeqSeen = Math.max(ch.maxSeqSeen, seq);
@@ -3895,21 +4005,47 @@ export class FanoutTree extends DirectStream {
3895
4005
  reservationToken,
3896
4006
  });
3897
4007
  }
3898
- async probeParentCandidate(ch, parentHash, timeoutMs, signal, minFreeSlots = 0, reserveRootCapacity = true) {
3899
- if (!this.peers.get(parentHash))
4008
+ async probeParentCandidate(ch, parentHash, timeoutMs, signal, minFreeSlots = 0, reserveRootCapacity = true, purpose = "upgrade") {
4009
+ const peer = this.peers.get(parentHash);
4010
+ if (!peer)
3900
4011
  return;
3901
- const reqId = (this.random() * 0xffffffff) >>> 0;
3902
- const p = new Promise((resolve) => {
3903
- ch.pendingParentProbe.set(reqId, { resolve });
3904
- });
3905
- await this._sendControl(parentHash, this.codec.encodeParentProbeReq(ch.id.key, reqId, minFreeSlots, reserveRootCapacity));
3906
- const res = await Promise.race([
3907
- p,
3908
- delay(Math.max(1, timeoutMs), { signal }).then(() => undefined),
3909
- ]);
3910
- if (!res)
3911
- ch.pendingParentProbe.delete(reqId);
3912
- return res;
4012
+ const controller = new AbortController();
4013
+ let reqId = (this.random() * 0xffffffff) >>> 0;
4014
+ while (ch.pendingParentProbe.has(reqId))
4015
+ reqId = (reqId + 1) >>> 0;
4016
+ let pending;
4017
+ let onAbort;
4018
+ let timer;
4019
+ try {
4020
+ return await new Promise((resolve, reject) => {
4021
+ pending = { peer, resolve };
4022
+ ch.pendingParentProbe.set(reqId, pending);
4023
+ onAbort = () => {
4024
+ const reason = signal.reason ?? new AbortError("fanout probe aborted");
4025
+ controller.abort(reason);
4026
+ reject(reason);
4027
+ };
4028
+ signal.addEventListener("abort", onAbort, { once: true });
4029
+ if (signal.aborted)
4030
+ return onAbort();
4031
+ // Bound signing/queueing as well as the reply; a stuck send must not
4032
+ // prevent the join loop from recovering or closing the channel.
4033
+ timer = setTimeout(() => {
4034
+ controller.abort(new AbortError("fanout probe timed out"));
4035
+ resolve(undefined);
4036
+ }, Math.max(1, timeoutMs));
4037
+ timer.unref?.();
4038
+ void this._sendControl(parentHash, this.codec.encodeParentProbeReq(ch.id.key, reqId, minFreeSlots, reserveRootCapacity), controller.signal, purpose).catch(() => resolve(undefined));
4039
+ });
4040
+ }
4041
+ finally {
4042
+ clearTimeout(timer);
4043
+ signal.removeEventListener("abort", onAbort);
4044
+ if (ch.pendingParentProbe.get(reqId) === pending) {
4045
+ ch.pendingParentProbe.delete(reqId);
4046
+ }
4047
+ controller.abort(new AbortError("fanout probe settled"));
4048
+ }
3913
4049
  }
3914
4050
  async _joinLoop(ch, joinOpts) {
3915
4051
  const retryMs = Math.max(1, Math.floor(joinOpts.retryMs ?? 200));
@@ -3972,6 +4108,8 @@ export class FanoutTree extends DirectStream {
3972
4108
  throwInitialJoinTimeout();
3973
4109
  };
3974
4110
  let nextParentUpgradeCheckAt = 0;
4111
+ let nextParentHealthProbeAt = 0;
4112
+ let failedParentProbe;
3975
4113
  let parentUpgradeCheckSeq = 0;
3976
4114
  let parentUpgradeActiveGuardBackoffMs = 0;
3977
4115
  const unsuccessfulColdBootstrapPeers = new Set();
@@ -4033,8 +4171,10 @@ export class FanoutTree extends DirectStream {
4033
4171
  }
4034
4172
  // Parent disappeared? Rejoin.
4035
4173
  if (ch.parent) {
4036
- const parentPeer = this.peers.get(ch.parent);
4174
+ const parentHash = ch.parent;
4175
+ const parentPeer = this.peers.get(parentHash);
4037
4176
  let connected = false;
4177
+ let probeFailed = false;
4038
4178
  if (parentPeer) {
4039
4179
  try {
4040
4180
  const conns = this.components.connectionManager.getConnections(parentPeer.peerId);
@@ -4044,8 +4184,49 @@ export class FanoutTree extends DirectStream {
4044
4184
  connected = parentPeer.isReadable || parentPeer.isWritable;
4045
4185
  }
4046
4186
  }
4187
+ const now = Date.now();
4188
+ if (now - ch.lastParentDataAt < PARENT_IDLE_PROBE_INTERVAL_MS) {
4189
+ failedParentProbe = undefined;
4190
+ }
4191
+ else if (connected &&
4192
+ parentPeer &&
4193
+ now >= nextParentHealthProbeAt) {
4194
+ const route = ch.routeFromRoot;
4195
+ const lastDataAt = ch.lastParentDataAt;
4196
+ const reply = await this.probeParentCandidate(ch, parentHash, parentUpgrade.probe.timeoutMs, signal, 0, false, "health");
4197
+ if (ch.closed ||
4198
+ signal.aborted ||
4199
+ this.channelsBySuffixKey.get(ch.id.suffixKey) !== ch ||
4200
+ ch.parent !== parentHash ||
4201
+ ch.routeFromRoot !== route ||
4202
+ this.peers.get(parentHash) !== parentPeer) {
4203
+ failedParentProbe = undefined;
4204
+ continue;
4205
+ }
4206
+ nextParentHealthProbeAt = Date.now() + PARENT_IDLE_PROBE_INTERVAL_MS;
4207
+ // A full parent is still healthy. Do not reserve capacity or
4208
+ // refresh lastParentDataAt: probes must not mask stalled data.
4209
+ if (reply || ch.lastParentDataAt !== lastDataAt) {
4210
+ failedParentProbe = undefined;
4211
+ }
4212
+ else if (failedParentProbe?.peer === parentPeer &&
4213
+ failedParentProbe.route === route) {
4214
+ probeFailed = true;
4215
+ connected = false;
4216
+ cooldownUntilByHash.set(parentHash, Date.now() + candidateCooldownMs);
4217
+ }
4218
+ else {
4219
+ failedParentProbe = { peer: parentPeer, route };
4220
+ nextParentHealthProbeAt = Date.now() + Math.max(retryMs, 1_000);
4221
+ }
4222
+ }
4047
4223
  if (!connected) {
4048
- ch.metrics.reparentDisconnect += 1;
4224
+ if (probeFailed)
4225
+ ch.metrics.reparentStale += 1;
4226
+ else
4227
+ ch.metrics.reparentDisconnect += 1;
4228
+ failedParentProbe = undefined;
4229
+ nextParentHealthProbeAt = 0;
4049
4230
  const hadChildren = ch.children.size > 0;
4050
4231
  this.detachFromParent(ch);
4051
4232
  nextParentUpgradeCheckAt = 0;
@@ -5914,11 +6095,7 @@ export class FanoutTree extends DirectStream {
5914
6095
  const want = Math.max(1, decoded.want);
5915
6096
  const ttlMs = Math.min(120_000, Math.max(1_000, decoded.ttlMs));
5916
6097
  const now = Date.now();
5917
- let watchers = this.providerWatchersBySuffixKey.get(suffixKey);
5918
- if (!watchers) {
5919
- watchers = new Map();
5920
- this.providerWatchersBySuffixKey.set(suffixKey, watchers);
5921
- }
6098
+ const watchers = this.touchProviderWatchers(suffixKey);
5922
6099
  watchers.set(fromHash, {
5923
6100
  hash: fromHash,
5924
6101
  want,
@@ -6033,8 +6210,12 @@ export class FanoutTree extends DirectStream {
6033
6210
  return false;
6034
6211
  const { reqId, ...reply } = decoded;
6035
6212
  const pending = ch.pendingParentProbe.get(reqId);
6036
- if (!pending)
6213
+ if (!pending ||
6214
+ pending.peer !== peerStream ||
6215
+ pending.peer.publicKey.hashcode() !== fromHash ||
6216
+ this.peers.get(fromHash) !== peerStream) {
6037
6217
  return true;
6218
+ }
6038
6219
  ch.pendingParentProbe.delete(reqId);
6039
6220
  pending.resolve(reply);
6040
6221
  this.touchPeerHint(ch, fromHash);
@@ -6245,7 +6426,8 @@ export class FanoutTree extends DirectStream {
6245
6426
  }
6246
6427
  void this.kickChildHashes(ch, [worstChild]).catch(() => { });
6247
6428
  }
6248
- ch.children.set(fromHash, { bidPerByte });
6429
+ const child = { bidPerByte };
6430
+ ch.children.set(fromHash, child);
6249
6431
  if (ch.isRoot && consumedParentUpgradeReservation) {
6250
6432
  ch.parentUpgradeTrackerNoCapacityUntil = Math.max(ch.parentUpgradeTrackerNoCapacityUntil, Date.now() + 2_000);
6251
6433
  }
@@ -6253,6 +6435,11 @@ export class FanoutTree extends DirectStream {
6253
6435
  const joinAccept = this.codec.encodeJoinAccept(ch.id.key, reqId, ch.level, ch.routeFromRoot, this.getHaveRange(ch));
6254
6436
  void (async () => {
6255
6437
  await this._sendControl(fromHash, joinAccept);
6438
+ if (ch.closed || ch.children.get(fromHash) !== child)
6439
+ return;
6440
+ this.dispatchEvent(new CustomEvent("fanout:child-joined", {
6441
+ detail: { topic: ch.id.topic, root: ch.id.root, child: fromHash },
6442
+ }));
6256
6443
  if (ch.endSeqExclusive > 0) {
6257
6444
  await this._sendControl(fromHash, this.codec.encodeEnd(ch.id.key, ch.endSeqExclusive));
6258
6445
  }
@@ -6635,6 +6822,22 @@ export class FanoutTree extends DirectStream {
6635
6822
  return true;
6636
6823
  }
6637
6824
  if (kind === MSG_KICK) {
6825
+ if (this.peers.get(fromHash) !== peerStream)
6826
+ return true;
6827
+ if (fromHash !== ch.parent) {
6828
+ if (ch.parentUpgradeGrace?.previousParent === fromHash) {
6829
+ // This attachment was evicted; never roll back to it.
6830
+ this.clearParentUpgradeGrace(ch);
6831
+ }
6832
+ if (ch.parentShadow?.hash === fromHash) {
6833
+ ch.parentShadow = undefined;
6834
+ ch.metrics.parentShadowReset += 1;
6835
+ if (this.parentUpgradeShadowInFlightSuffixKey === ch.id.suffixKey) {
6836
+ this.parentUpgradeShadowInFlightSuffixKey = undefined;
6837
+ }
6838
+ }
6839
+ return true;
6840
+ }
6638
6841
  ch.metrics.reparentKicked += 1;
6639
6842
  ch.parent = undefined;
6640
6843
  ch.level = Number.POSITIVE_INFINITY;