feat(admin): replace dead ThreadPool counters with a network readout (#2663)
## Summary
The admin gump's **Performance** page still rendered `ThreadPool` worker / IOCP quotas — a RunUO leftover from `Socket.BeginReceive` days. Both figures are dead: IORingGroup drives RIO / io_uring / epoll / kqueue synchronously on the game loop, so the IOCP figure reads 0% forever, and the real off-loop work (serialization workers, password checks, advanced search, console input) runs on dedicated threads the worker figure never sees.
This replaces the block with a read-only network readout.
## Engine
- `NetState.GetNetworkStats()` — new public accessor returning a `NetworkStats` snapshot (ModernUO-owned record types in `Network/NetworkStats.cs`, so UOContent takes no dependency on transport types):
- live: connected / max sockets, authenticated count, per-tier growth usage, the three loop queues (throttled, flush pending, pending disconnects)
- configured: base / pre-auth / max buffer sizes, growth budget, memory ceiling, last-read available memory
- `LastSweep`: everything the once-a-minute maintenance sweep saw, including the refusal counters it resets
- The sweep already kept four of its results (`_lastTier*`, `_lastBaseCapacityBytes`) for change detection; those fold into one `SendBufferSweep` snapshot. Sweep logic and logging are unchanged.
- The accessor never calls `Maintain()`, so opening the page cannot rotate the retention window.
- Tick age is compared by subtraction; "has a sweep run" is a `bool`, not a zero-tick sentinel.
## Gump
```
Event Loop: Healthy
Connections: 123 / 4096 (117 authenticated)
Loop Queues: throttled 0, flush 3, closing 0
Send Buffers: [scrollable]
Base: 64.0 KB recv, 256.0 KB send; pre-auth 4.0 KB / 4.0 KB
Base pools: 10.2 MB
Growth tiers (live):
512.0 KB: 3 / 32 in use, floor 5
1.0 MB: 0 / 0 in use, floor 0
2.0 MB: 0 / 0 in use, floor 0
Budget: 16.0 MB of 256.0 MB, max 2.0 MB per socket
Ceiling: 80% of 7.8 GB available
Last sweep 42s ago: released 0 tier, 0 base
Refused: budget 0, at max 0, ceiling 0
```
This commit is contained in:
parent
24bcfee554
commit
29a3ab1bd4
4 changed files with 280 additions and 30 deletions
|
|
@ -56,10 +56,7 @@ public partial class NetState
|
|||
internal static long _availableMemoryBytes;
|
||||
|
||||
private static Timer.DelayCallTimer _maintenanceTimer;
|
||||
private static long _lastTierCapacityBytes;
|
||||
private static int _lastTierInUse;
|
||||
private static int _lastTierRetainFloor;
|
||||
private static long _lastBaseCapacityBytes;
|
||||
private static SendBufferSweep _lastSweep;
|
||||
|
||||
private static readonly Queue<NetState> _disposed = [];
|
||||
private static readonly TimeSpan ConnectingSocketIdleLimit = TimeSpan.FromMilliseconds(5000); // 5 seconds
|
||||
|
|
@ -238,14 +235,23 @@ public partial class NetState
|
|||
_capRefusals = 0;
|
||||
|
||||
var stats = _socketManager.Maintain();
|
||||
var changed = stats.TierCapacityBytes != _lastTierCapacityBytes ||
|
||||
stats.TierInUse != _lastTierInUse ||
|
||||
stats.TierRetainFloor != _lastTierRetainFloor ||
|
||||
stats.BaseCapacityBytes != _lastBaseCapacityBytes;
|
||||
_lastTierCapacityBytes = stats.TierCapacityBytes;
|
||||
_lastTierInUse = stats.TierInUse;
|
||||
_lastTierRetainFloor = stats.TierRetainFloor;
|
||||
_lastBaseCapacityBytes = stats.BaseCapacityBytes;
|
||||
var changed = stats.TierCapacityBytes != _lastSweep.TierCapacityBytes ||
|
||||
stats.TierInUse != _lastSweep.TierInUse ||
|
||||
stats.TierRetainFloor != _lastSweep.TierRetainFloor ||
|
||||
stats.BaseCapacityBytes != _lastSweep.BaseCapacityBytes;
|
||||
_lastSweep = new SendBufferSweep(
|
||||
true,
|
||||
Core.TickCount,
|
||||
stats.TierCapacityBytes,
|
||||
stats.TierInUse,
|
||||
stats.TierRetainFloor,
|
||||
stats.BuffersReleased,
|
||||
stats.BaseCapacityBytes,
|
||||
stats.BaseBuffersReleased,
|
||||
stats.GrowthRefusals,
|
||||
capRefusals,
|
||||
ceilingRefusals
|
||||
);
|
||||
|
||||
// Quiet unless something moved
|
||||
if (changed || stats.BuffersReleased > 0 || stats.BaseBuffersReleased > 0 || stats.GrowthRefusals > 0 ||
|
||||
|
|
@ -266,6 +272,48 @@ public partial class NetState
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read-only diagnostics snapshot; never rotates the maintenance window. Cold path: allocates.
|
||||
/// </summary>
|
||||
public static NetworkStats GetNetworkStats()
|
||||
{
|
||||
var manager = _socketManager;
|
||||
var tiers = manager == null ? [] : new SendBufferTierUsage[manager.SendBufferTierCount];
|
||||
for (var i = 0; i < tiers.Length; i++)
|
||||
{
|
||||
var tier = manager.GetSendBufferTierStats(i);
|
||||
tiers[i] = new SendBufferTierUsage(tier.BufferSize, tier.Capacity, tier.InUse, tier.RetainFloor);
|
||||
}
|
||||
|
||||
var authenticated = 0;
|
||||
foreach (var ns in _instances)
|
||||
{
|
||||
if (ns.Account != null)
|
||||
{
|
||||
authenticated++;
|
||||
}
|
||||
}
|
||||
|
||||
return new NetworkStats(
|
||||
manager?.ConnectedCount ?? 0,
|
||||
manager?.MaxSockets ?? MaxConnections,
|
||||
authenticated,
|
||||
RecvBufferSize,
|
||||
SendBufferSize,
|
||||
MaxSendBufferSize,
|
||||
InitialRecvBufferSize,
|
||||
InitialSendBufferSize,
|
||||
_sendBufferGrowthBudget,
|
||||
_memoryCeilingPercent,
|
||||
_availableMemoryBytes,
|
||||
tiers,
|
||||
_lastSweep,
|
||||
_throttled.Count + _throttledPending.Count,
|
||||
_flushPending.Count,
|
||||
_pendingDisconnects.Count
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Slabs each base pool is divided into, after the transport applies its minimum slab size.
|
||||
/// </summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue