History

Re-arm the probe retry when an effect rerun cancels it

Rhys Sullivan committed 1 month ago

Commit 0265b4f1 parent 0526dc81 file · +13 −1Browse files

Unified · Split

packages/react/src/lib/use-connection-health.ts+13−1
@@ -328,7 +328,14 @@ export function useConnectionHealth(connection: Connection): { · 327 unmodified lines
328328 // freshness window, not the floor, is what suppressed it).
329329 const delay = autoProbeRetryDelayMs(key);
330330 if (delay === null) return;
331+ // The decision is NOT final while the timer is pending: roll the epoch
332+ // back to "unseen" so an effect rerun (a new `connection` identity from a
333+ // list refetch, a scope change) that cancels this timer re-enters the
334+ // decision above and re-arms it, instead of treating the epoch as already
335+ // handled and leaving the row suppressed until the next remount.
336+ seenEpoch.current = undefined;
331337 const timer = setTimeout(() => {
338+ seenEpoch.current = epoch;
332339 if (shouldAutoProbe(key, last)) probe();
333340 }, delay);
334341 return () => clearTimeout(timer);
@@ -433,11 +440,16 @@ export function useConnectionsHealth( · 98 unmodified lines
433440 probe();
434441 continue;
435442 }
436− // Same bounded suppression as the single-connection hook.
443+ // Same bounded suppression as the single-connection hook, and the same
444+ // rule for a pending timer: the row is NOT yet considered for this
445+ // epoch, so a rerun (the list re-merging as owners' rows arrive) that
446+ // clears the timers re-enters the decision and re-arms it.
437447 const delay = autoProbeRetryDelayMs(memoryKey);
438448 if (delay === null) continue;
449+ revalidated.current.delete(key);
439450 timers.push(
440451 setTimeout(() => {
452+ revalidated.current.set(key, epoch);
441453 if (shouldAutoProbe(memoryKey, last)) probe();
442454 }, delay),
443455 );