-
-
Notifications
You must be signed in to change notification settings - Fork 4
Feature: Packet Back‐Pressure
This feature puts hard budgets around packet enqueue and main-thread dispatch.
StratumPacketBackPressure protects ClientPackets with four constraints:
- max queued packets per client at enqueue time
- max wall-clock time per tick
- max packets per client per tick
- deferred packet requeueing when a client hits its per-tick dispatch cap
The point is fairness and tick stability, not max throughput at any cost.
StratumPacketBackPressureConfig:
public bool Enabled { get; set; } = true;
public int MaxMillisecondsPerTick { get; set; } = 25;
public int MaxPacketsPerClientPerTick { get; set; } = 32;
public int MaxQueueDepthPerClient { get; set; } = 2000;
public bool KickOnQueueOverflow { get; set; } = true;
public string KickMessage { get; set; } = "Disconnected by Stratum packet back-pressure";ServerMain calls TryRegisterEnqueue(...) for new connections, disconnects, and parsed client packets before putting them on ClientPackets.
if (StratumRuntime.PacketBackPressure.TryRegisterEnqueue(item, out string disconnectReason))
{
ClientPackets.Enqueue(item);
return;
}That records per-client queue depth immediately, so a flooding client cannot hide behind a slow main-thread drain. If the depth crosses MaxQueueDepthPerClient, Stratum rejects that packet at enqueue time and queues a disconnect packet instead.
From StratumPacketBackPressure.DrainAndDispatch(...), dispatch still respects wall-clock and per-client caps:
long start = Stopwatch.GetTimestamp();
long budgetTicks = (long)maxMs * ticksPerMs;
while (true)
{
if (Stopwatch.GetTimestamp() - start >= budgetTicks) break;
if (!source.TryDequeue(out ReceivedClientPacket pkt)) break;
servedThisTick.TryGetValue(cid, out int served);
if (served >= perClientCap)
{
deferred.Add(pkt);
continue;
}
dispatch(pkt);
MarkPacketFinished(pkt);
dispatched++;
servedThisTick[cid] = served + 1;
}Deferred packets are requeued for the next tick:
for (int i = 0; i < deferredCount; i++)
{
source.Enqueue(deferred[i]);
}If queue overflow kicking is enabled and a client's tracked queue depth crosses the threshold, the enqueue guard rejects that packet and schedules a disconnect packet with KickMessage.
if (queued > queueKick)
{
totalRejectedAtEnqueue++;
disconnectReason = bp.KickOnQueueOverflow ? bp.KickMessage : null;
return false;
}ServerMain uses EnqueueStratumClientPacket(...) for enqueue-time accounting and StratumRuntime.PacketBackPressure.DrainAndDispatch(...) instead of unbounded queue drain.
The packet report includes enqueue rejections and queue-depth telemetry:
rejectedAtEnqueue=...
queueDepth=...
peakQueueDepth=...
sources/VintagestoryLib/Vintagestory.Server/StratumPacketBackPressure.cs-
sources/VintagestoryLib/Vintagestory.Server/StratumConfig.cs(StratumPacketBackPressureConfig) patches/VintagestoryLib/Vintagestory.Server/ServerMain.cs.patch