Files
Playa/hosts/Volcanic.AgenticCore.Telegram/Polling/ReconnectPolicy.cs

28 lines
1.3 KiB
C#

namespace Volcanic.AgenticCore.Telegram.Polling;
/// <summary>
/// Exponential backoff with jitter for consecutive polling failures. Thread-safe: failures are counted by the polling
/// loop, the reset comes from the HTTP response callback.
/// </summary>
public sealed class ReconnectPolicy(TimeSpan initialDelay, TimeSpan maxDelay, double jitter = 0.2, Random? random = null)
{
private readonly Random _random = random ?? Random.Shared;
private int _failures;
/// <summary>Consecutive failures since the last success.</summary>
public int Failures => Volatile.Read(ref _failures);
/// <summary>Record a failure and return how long to wait before the next attempt.</summary>
public TimeSpan NextDelay()
{
var failures = Interlocked.Increment(ref _failures);
var exponent = Math.Min(failures - 1, 30);
var ms = Math.Min(maxDelay.TotalMilliseconds, initialDelay.TotalMilliseconds * Math.Pow(2, exponent));
var factor = 1 + ((_random.NextDouble() * 2) - 1) * jitter;
return TimeSpan.FromMilliseconds(Math.Max(0, ms * factor));
}
/// <summary>Record a success. Returns the number of failures it ends (0 when the connection was healthy).</summary>
public int Reset() => Interlocked.Exchange(ref _failures, 0);
}