Política Hedge
La política hedge inicia una solicitud especulativa paralela si la original no se completa dentro de un retardo. La que termine primero gana; las demás se cancelan.
Uso Básico
var policy = ResiliencePolicy.Create()
.Hedge(TimeSpan.FromMilliseconds(100)) // iniciar hedge si la original tarda > 100ms
.Build();
Opciones de Configuración
var policy = ResiliencePolicy.Create()
.Hedge(opts =>
{
opts.HedgeDelay = TimeSpan.FromMilliseconds(100);
opts.MaxHedgedAttempts = 2;
opts.OnHedge = context =>
{
_logger.LogDebug("Intento hedge #{Attempt} iniciado", context.AttemptNumber);
return Task.CompletedTask;
};
})
.Build();
Hedge por Predicado de Resultado
var policy = ResiliencePolicy.Create()
.Hedge(opts =>
{
opts.HedgeDelay = TimeSpan.FromMilliseconds(50);
opts.MaxHedgedAttempts = 1;
// Hedge si el resultado indica respuesta degradada
opts.ShouldHedgeOnResult = result =>
result is string s && s.Contains("degraded");
})
.Build();
Manejo de Excepciones
Por defecto, las excepciones de los intentos hedgeados se suprimen — si todos los intentos fallan, el ejecutor retorna default (null para tipos de referencia):
// Comportamiento por defecto: excepciones suprimidas, retorna null en todos los fallos
string? result = await policy.ExecuteAsync<string>(ct =>
throw new HttpRequestException("Error de red"));
// result == null
nota
La política hedge está optimizada para reducción de latencia, no para recuperación de errores. Para recuperación de errores, usa Retry. Combina Retry + Hedge cuando necesitas ambos.
Ejemplo Completo: Búsqueda de Baja Latencia
var searchPolicy = ResiliencePolicy.Create()
.Hedge(opts =>
{
opts.HedgeDelay = TimeSpan.FromMilliseconds(200);
opts.MaxHedgedAttempts = 1;
})
.Timeout(TimeSpan.FromSeconds(2))
.Build();
SearchResult result = await searchPolicy.ExecuteAsync<SearchResult>(async ct =>
await _searchService.QueryAsync(query, ct));