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