Skip to content

Commit

Permalink
Reduce the overhead of updating the activity timeout timer (#2475)
Browse files Browse the repository at this point in the history
  • Loading branch information
MihaZupan committed Apr 16, 2024
1 parent f766c0d commit 308318e
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/ReverseProxy/Utilities/ActivityCancellationTokenSource.cs
Expand Up @@ -10,6 +10,11 @@ namespace Yarp.ReverseProxy.Utilities;

internal sealed class ActivityCancellationTokenSource : CancellationTokenSource
{
// Avoid paying the cost of updating the timeout timer if doing so won't meaningfully affect
// the overall timeout duration (default is 100s). This is a trade-off between precision and performance.
// The exact value is somewhat arbitrary, but should be large enough to avoid most timer updates.
private const int TimeoutResolutionMs = 20;

private const int MaxQueueSize = 1024;
private static readonly ConcurrentQueue<ActivityCancellationTokenSource> _sharedSources = new();
private static int _count;
Expand All @@ -22,18 +27,32 @@ internal sealed class ActivityCancellationTokenSource : CancellationTokenSource
};

private int _activityTimeoutMs;
private uint _lastTimeoutTicks;
private CancellationTokenRegistration _linkedRegistration1;
private CancellationTokenRegistration _linkedRegistration2;

private ActivityCancellationTokenSource() { }

public bool CancelledByLinkedToken { get; private set; }

public void ResetTimeout()
private void StartTimeout()
{
_lastTimeoutTicks = (uint)Environment.TickCount;
CancelAfter(_activityTimeoutMs);
}

public void ResetTimeout()
{
var currentMs = (uint)Environment.TickCount;
var elapsedMs = currentMs - _lastTimeoutTicks;

if (elapsedMs > TimeoutResolutionMs)
{
_lastTimeoutTicks = currentMs;
CancelAfter(_activityTimeoutMs);
}
}

public static ActivityCancellationTokenSource Rent(TimeSpan activityTimeout, CancellationToken linkedToken1 = default, CancellationToken linkedToken2 = default)
{
if (_sharedSources.TryDequeue(out var cts))
Expand All @@ -48,7 +67,7 @@ public static ActivityCancellationTokenSource Rent(TimeSpan activityTimeout, Can
cts._activityTimeoutMs = (int)activityTimeout.TotalMilliseconds;
cts._linkedRegistration1 = linkedToken1.UnsafeRegister(_linkedTokenCancelDelegate, cts);
cts._linkedRegistration2 = linkedToken2.UnsafeRegister(_linkedTokenCancelDelegate, cts);
cts.ResetTimeout();
cts.StartTimeout();

return cts;
}
Expand Down

0 comments on commit 308318e

Please sign in to comment.