// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Threading;
using ManagedCommon;
namespace PowerDisplay.Common.Utils
{
///
/// Helper class for executing operations with retry logic.
/// Provides a unified retry pattern for DDC/CI operations that may fail intermittently.
///
public static class RetryHelper
{
///
/// Default delay between retry attempts in milliseconds.
///
public const int DefaultRetryDelayMs = 100;
///
/// Default maximum number of retry attempts.
///
public const int DefaultMaxRetries = 3;
///
/// Executes a synchronous operation with retry logic.
///
/// The return type of the operation.
/// The operation to execute.
/// Predicate to determine if the result is valid.
/// Maximum number of retry attempts (default: 3).
/// Delay between retries in milliseconds (default: 100).
/// Optional name for logging purposes.
/// The result of the operation, or default if all retries failed.
public static T? ExecuteWithRetry(
Func operation,
Func isValid,
int maxRetries = DefaultMaxRetries,
int delayMs = DefaultRetryDelayMs,
string? operationName = null)
{
for (int attempt = 0; attempt < maxRetries; attempt++)
{
try
{
var result = operation();
if (isValid(result))
{
if (attempt > 0 && !string.IsNullOrEmpty(operationName))
{
Logger.LogDebug($"[Retry] {operationName} succeeded on attempt {attempt + 1}");
}
return result;
}
if (attempt < maxRetries - 1)
{
if (!string.IsNullOrEmpty(operationName))
{
Logger.LogWarning($"[Retry] {operationName} returned invalid result on attempt {attempt + 1}, retrying...");
}
Thread.Sleep(delayMs);
}
}
catch (Exception ex)
{
if (attempt < maxRetries - 1)
{
if (!string.IsNullOrEmpty(operationName))
{
Logger.LogWarning($"[Retry] {operationName} failed on attempt {attempt + 1}: {ex.Message}, retrying...");
}
Thread.Sleep(delayMs);
}
else
{
if (!string.IsNullOrEmpty(operationName))
{
Logger.LogWarning($"[Retry] {operationName} failed after {maxRetries} attempts: {ex.Message}");
}
}
}
}
if (!string.IsNullOrEmpty(operationName))
{
Logger.LogWarning($"[Retry] {operationName} failed after {maxRetries} attempts");
}
return default;
}
}
}