feat: add consecutive short-read counter to prevent buffer oscillation (Gap 5.10)
Require 4 consecutive short reads before shrinking AdaptiveReadBuffer, matching the Go server's readLoop behaviour and preventing buffer size thrashing.
This commit is contained in:
@@ -1,19 +1,44 @@
|
||||
namespace NATS.Server.IO;
|
||||
|
||||
/// <summary>
|
||||
/// Dynamically sized read buffer that grows on full reads and shrinks
|
||||
/// only after consecutive short reads exceed a threshold.
|
||||
/// Go reference: server/client.go — readLoop buffer sizing with short-read counter.
|
||||
/// </summary>
|
||||
public sealed class AdaptiveReadBuffer
|
||||
{
|
||||
private const int ShortReadThreshold = 4;
|
||||
private int _target = 4096;
|
||||
private int _consecutiveShortReads;
|
||||
|
||||
public int CurrentSize => Math.Clamp(_target, 512, 64 * 1024);
|
||||
|
||||
/// <summary>Number of consecutive short reads since last full read or grow.</summary>
|
||||
public int ConsecutiveShortReads => _consecutiveShortReads;
|
||||
|
||||
public void RecordRead(int bytesRead)
|
||||
{
|
||||
if (bytesRead <= 0)
|
||||
return;
|
||||
|
||||
if (bytesRead >= _target)
|
||||
{
|
||||
_target = Math.Min(_target * 2, 64 * 1024);
|
||||
_consecutiveShortReads = 0; // Reset on grow
|
||||
}
|
||||
else if (bytesRead < _target / 4)
|
||||
_target = Math.Max(_target / 2, 512);
|
||||
{
|
||||
_consecutiveShortReads++;
|
||||
if (_consecutiveShortReads >= ShortReadThreshold)
|
||||
{
|
||||
_target = Math.Max(_target / 2, 512);
|
||||
_consecutiveShortReads = 0; // Reset after shrink
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Medium read — not short, not full. Reset counter.
|
||||
_consecutiveShortReads = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user