using System; using System.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; namespace HikvisionAttendanceService; /// Exponential backoff retries for transient HTTP / network failures. internal static class UserSyncRetryHelper { /// 0-based attempt index: delays 1s, 2s, 4s, ... capped at 30s. 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); } /// Returns true if the HTTP status may succeed on retry. 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); } }