fix(site-runtime): ConnectionQualityChanged(Good) only resets the tag-subscribe backoff while it is stretched — a flapping connection can no longer defer the retry it was meant to hasten

Review finding on ab08ecd3: each Good re-armed the watchdog from 'now', so Goods arriving faster than the floor starved the retry. Pinned by FlappingGood_DoesNotDeferTheRetry (12 Goods over 1.2 s; naive re-arm measured 1.43 s, guarded ~0.3 s).

Claude-Session: https://claude.ai/code/session_019ZxXT5sxZs5XrtdwYzJDPV
This commit is contained in:
Joseph Doherty
2026-08-28 14:57:30 -04:00
parent 150c3f60d8
commit 0589486f4e
2 changed files with 42 additions and 1 deletions
@@ -1177,9 +1177,13 @@ public class InstanceActor : ReceiveActor
// TagSubscribeRetryMaxIntervalMs — recovery must be prompt. Timer != null ⇔ the
// subscribe is unconfirmed (it is only nulled by a Success); if a request is in
// flight and young the re-armed tick just hits the guard and re-arms at the floor.
// Only acts while the interval is actually stretched: once reset to the floor a
// further Good is a no-op, so a flapping connection cannot keep pushing the armed
// tick out and starve the retry it was meant to hasten.
if (qualityChanged.Quality == QualityCode.Good
&& _tagSubscribeStates.TryGetValue(qualityChanged.ConnectionName, out var subState)
&& subState.Timer != null)
&& subState.Timer != null
&& subState.Interval > TimeSpan.FromMilliseconds(_options.TagSubscribeRetryIntervalMs))
{
ResetTagSubscribeBackoff(subState);
ArmTagSubscribeWatchdog(qualityChanged.ConnectionName, subState);