hikvision-sync-service/UserSyncRetryHelper.cs

54 lines
1.7 KiB
C#

using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace HikvisionAttendanceService;
/// <summary>Exponential backoff retries for transient HTTP / network failures.</summary>
internal static class UserSyncRetryHelper
{
/// <summary>0-based attempt index: delays 1s, 2s, 4s, ... capped at 30s.</summary>
public static int GetBackoffDelayMilliseconds(int zeroBasedAttemptIndex)
{
if (zeroBasedAttemptIndex < 0)
zeroBasedAttemptIndex = 0;
double seconds = Math.Pow(2, zeroBasedAttemptIndex);
var ms = (int)(seconds * 1000);
return Math.Min(ms, 30_000);
}
/// <summary>Returns true if the HTTP status may succeed on retry.</summary>
public static bool IsTransientHttpStatus(HttpStatusCode code)
{
var n = (int)code;
if (n == 408 || n == 429)
return true;
if (n >= 500 && n <= 599)
return true;
return false;
}
public static bool ShouldRetryException(Exception ex)
{
if (ex is HttpRequestException || ex is TaskCanceledException)
return true;
return false;
}
public static void SleepBackoff(int zeroBasedAttemptIndex, CancellationToken ct)
{
ct.ThrowIfCancellationRequested();
var delay = GetBackoffDelayMilliseconds(zeroBasedAttemptIndex);
Thread.Sleep(delay);
ct.ThrowIfCancellationRequested();
}
public static async Task DelayBackoffAsync(int zeroBasedAttemptIndex, CancellationToken ct)
{
var delay = GetBackoffDelayMilliseconds(zeroBasedAttemptIndex);
await Task.Delay(delay, ct).ConfigureAwait(false);
}
}