This commit is contained in:
gregw 2024-09-27 16:41:46 +10:00
parent 65252a3701
commit 40a68bf238
1 changed files with 26 additions and 1 deletions

View File

@ -113,6 +113,8 @@ public class DoSHandler extends ConditionalHandler.ElseNext
interface Factory
{
RateControl newRateControl();
Duration idleCheckPeriod();
}
}
@ -206,9 +208,15 @@ public class DoSHandler extends ConditionalHandler.ElseNext
// Try shrinking the tracker pool
long now = NanoTime.now();
_trackers.values().removeIf(tracker -> tracker.isIdle(now));
if (_trackers.size() >= _maxTrackers)
{
// Try shrinking the tracker pool as if we are at the next idle check already
long nextIdleCheck = NanoTime.now() + _rateControlFactory.idleCheckPeriod().getNano();
_trackers.values().removeIf(tracker -> tracker.isIdle(nextIdleCheck));
if (_trackers.size() >= _maxTrackers)
return _rejectHandler.handle(request, response, callback);
}
}
// Calculate an id for the request (which may be global empty string)
String id = _getId.apply(request);
@ -349,6 +357,7 @@ public class DoSHandler extends ConditionalHandler.ElseNext
public static class ExponentialMovingAverageRateControlFactory implements RateControl.Factory
{
private final Duration _samplePeriod;
private final Duration _idleCheckPeriod;
private final double _alpha;
private final int _maxRequestsPerSecond;
@ -374,8 +383,18 @@ public class DoSHandler extends ConditionalHandler.ElseNext
@Name("samplePeriod") Duration samplePeriod,
@Name("alpha") double alpha,
@Name("maxRequestsPerSecond") int maxRequestsPerSecond)
{
this(samplePeriod, null, alpha, maxRequestsPerSecond);
}
public ExponentialMovingAverageRateControlFactory(
@Name("samplePeriod") Duration samplePeriod,
@Name("idleCheckPeriod") Duration idleCheckPeriod,
@Name("alpha") double alpha,
@Name("maxRequestsPerSecond") int maxRequestsPerSecond)
{
_samplePeriod = samplePeriod == null ? Duration.ofMillis(100) : samplePeriod;
_idleCheckPeriod = idleCheckPeriod == null ? _samplePeriod.multipliedBy(20) : idleCheckPeriod;
_alpha = alpha <= 0.0 ? 0.2 : alpha;
if (_samplePeriod.compareTo(Duration.ofSeconds(1)) > 0)
throw new IllegalArgumentException("Sample period must be less than or equal to 1 second");
@ -384,6 +403,12 @@ public class DoSHandler extends ConditionalHandler.ElseNext
_maxRequestsPerSecond = maxRequestsPerSecond;
}
@Override
public Duration idleCheckPeriod()
{
return _idleCheckPeriod;
}
@Override
public RateControl newRateControl()
{