From 87051737da048ec9315675986f24befa15a7285a Mon Sep 17 00:00:00 2001 From: gamer147 Date: Sun, 31 May 2026 22:02:56 -0400 Subject: [PATCH] feat(battle-node): InboundTracker dedupes client pubSeq + tracks high-water --- .../Reliability/InboundTracker.cs | 20 +++++++++ .../Reliability/InboundTrackerTests.cs | 41 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 SVSim.BattleNode/Reliability/InboundTracker.cs create mode 100644 SVSim.UnitTests/BattleNode/Reliability/InboundTrackerTests.cs diff --git a/SVSim.BattleNode/Reliability/InboundTracker.cs b/SVSim.BattleNode/Reliability/InboundTracker.cs new file mode 100644 index 0000000..199e412 --- /dev/null +++ b/SVSim.BattleNode/Reliability/InboundTracker.cs @@ -0,0 +1,20 @@ +namespace SVSim.BattleNode.Reliability; + +/// +/// Per-session inbound-emit ledger. Dedupes the client's pubSeq so we never dispatch +/// a retransmitted emit twice; ack-echo (via SIO callback) is the caller's job. +/// +public sealed class InboundTracker +{ + private readonly HashSet _seen = new(); + + /// Highest pubSeq observed so far. Reported via Gungnir for diagnostics. + public long HighWaterMark { get; private set; } + + /// Record an incoming pubSeq. Returns true if the caller should dispatch the envelope, false on duplicate. + public bool Observe(long pubSeq) + { + if (pubSeq > HighWaterMark) HighWaterMark = pubSeq; + return _seen.Add(pubSeq); + } +} diff --git a/SVSim.UnitTests/BattleNode/Reliability/InboundTrackerTests.cs b/SVSim.UnitTests/BattleNode/Reliability/InboundTrackerTests.cs new file mode 100644 index 0000000..d811786 --- /dev/null +++ b/SVSim.UnitTests/BattleNode/Reliability/InboundTrackerTests.cs @@ -0,0 +1,41 @@ +using NUnit.Framework; +using SVSim.BattleNode.Reliability; + +namespace SVSim.UnitTests.BattleNode.Reliability; + +[TestFixture] +public class InboundTrackerTests +{ + [Test] + public void Observe_FirstSeenPubSeq_ReturnsDispatchTrue() + { + var t = new InboundTracker(); + Assert.That(t.Observe(pubSeq: 1), Is.True); + } + + [Test] + public void Observe_SamePubSeqTwice_SecondReturnsFalse() + { + var t = new InboundTracker(); + t.Observe(1); + Assert.That(t.Observe(1), Is.False); + } + + [Test] + public void Observe_DifferentPubSeqs_BothDispatch() + { + var t = new InboundTracker(); + Assert.That(t.Observe(1), Is.True); + Assert.That(t.Observe(2), Is.True); + } + + [Test] + public void HighWaterMark_TracksHighestObserved() + { + var t = new InboundTracker(); + t.Observe(3); + t.Observe(1); + t.Observe(5); + Assert.That(t.HighWaterMark, Is.EqualTo(5)); + } +}