perf(inventory): jitter the flush interval (2-5 min, re-rolled per tick)
The 60s fixed flush made the whole fleet flush in lockstep after an auto-update relog wave (timers phase-aligned), producing a synchronized burst that starved backend telemetry → player-count flapping. Now each client flushes on a random 2-5 min interval (2 min base + up to 3 min jitter), re-rolled after every tick, so timers continuously drift apart and never re-synchronize — even when many clients hot-reload at the same instant. Inventory is up to 5 min stale by design. Pairs with the backend concurrency cap as defense-in-depth. Built on master (placeholder secret, works via SHARED_SECRET_LEGACY); the websocket_secret.txt change stays parked on secret-rollout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
92a51b205c
commit
4fdec3bbcd
2 changed files with 22 additions and 2 deletions
|
|
@ -24,13 +24,27 @@ namespace MosswartMassacre
|
|||
// so the backend sees ~1 update per item per flush instead of many per
|
||||
// second. Adds and removes stay immediate (they're rare and meaningful).
|
||||
private readonly HashSet<int> _dirtyItemIds = new HashSet<int>();
|
||||
private const int FlushIntervalMs = 60000; // 60s — tune here if needed
|
||||
// Flush on a RANDOMIZED interval — 2 minutes plus up to 3 more (so
|
||||
// 2–5 min) — re-rolled after every tick. This de-synchronizes the
|
||||
// fleet: even when many clients hot-reload at once (an auto-update
|
||||
// wave) and start their timers at the same instant, each picks a
|
||||
// different interval, so their flushes spread out instead of arriving
|
||||
// at the backend as one synchronized burst (which starved telemetry
|
||||
// and made the player count flap).
|
||||
private const int FlushBaseMs = 120000; // 2 minutes
|
||||
private const int FlushJitterMs = 180000; // + up to 3 minutes → 2–5 min
|
||||
private readonly Random _rng = new Random();
|
||||
private readonly System.Windows.Forms.Timer _flushTimer;
|
||||
|
||||
private int NextFlushIntervalMs()
|
||||
{
|
||||
return FlushBaseMs + _rng.Next(0, FlushJitterMs + 1); // 120000–300000 ms
|
||||
}
|
||||
|
||||
internal LiveInventoryTracker(IPluginLogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_flushTimer = new System.Windows.Forms.Timer { Interval = FlushIntervalMs };
|
||||
_flushTimer = new System.Windows.Forms.Timer { Interval = NextFlushIntervalMs() };
|
||||
_flushTimer.Tick += FlushDirtyItems;
|
||||
}
|
||||
|
||||
|
|
@ -53,6 +67,7 @@ namespace MosswartMassacre
|
|||
{
|
||||
_logger?.Log($"[LiveInv] Error initializing: {ex.Message}");
|
||||
}
|
||||
_flushTimer.Interval = NextFlushIntervalMs(); // fresh random phase per login
|
||||
_flushTimer.Start();
|
||||
}
|
||||
|
||||
|
|
@ -148,6 +163,11 @@ namespace MosswartMassacre
|
|||
/// </summary>
|
||||
private void FlushDirtyItems(object sender, EventArgs e)
|
||||
{
|
||||
// Re-roll the interval every tick so the fleet's timers keep
|
||||
// drifting apart and never re-synchronize. (Setting Interval on a
|
||||
// WinForms timer restarts its countdown — desired here.)
|
||||
_flushTimer.Interval = NextFlushIntervalMs();
|
||||
|
||||
if (_dirtyItemIds.Count == 0) return;
|
||||
|
||||
// Snapshot then clear, so changes arriving during the flush are
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue