es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Polly Retry – Ejecutar todo hasta que se logre un reintentimiento exitoso.

Actualmente, la política de reintento de Polly reintenta todas las solicitudes fallidas de forma independiente. Entonces, si hay 10 solicitudes fallidas y he configurado la política de reintento infinito, enviará 10 solicitudes más cada vez que ocurra un reintento y el servidor nunca se recuperará.

¿Cómo pasar de forma asíncrona todas las solicitudes fallidas y reintentar solo una solicitud y reanudar el flujo normal si el reintento tiene éxito?

No puedo (no quiero) usar el Breaker de Circuito porque mi servicio es un servicio de trabajador en segundo plano y el Breaker de Circuito interrumpe toda la lógica del servicio de fondo.

Código actual solo con política de reintento

var retry = HttpPolicyExtensions.HandleTransientHttpError().WaitAndRetryForeverAsync(retryNo => new TimeSpan(0, retryNo > 3 ? 10 : (retryNo * 2), 0));
builder.Services.AddHttpClient<testclient>().AddPolicyHandler(retry);

Caso de uso: he escrito un servicio en segundo plano que raspas continuamente un sitio web que contiene más de 30000 páginas. Para evitar sobrecargar el sitio, estoy usando SemaphoreSlim (o Bulkhead) para limitar la cantidad de solicitudes que se envían al servidor en un momento dado.

Aún así, existe la posibilidad de que el servidor rechace mi solicitud. En ese momento, necesito reintentar solo una solicitud fallida hasta que el servidor vuelva a aceptar mi solicitud. Dado que estoy enviando varias solicitudes al mismo tiempo, Polly está reintentando todas las solicitudes fallidas, lo que hace que el servidor no esté contento.

Expectativa:

10 solicitudes fallidas -> Reintentar 1 solicitud (hasta el éxito) -> Si tiene éxito, volver a enviar las 9 solicitudes restantes.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para pasar de forma asíncrona todas las solicitudes fallidas y reintentar solo una solicitud y reanudar el flujo normal si el reintento es exitoso, es necesario modificar la implementación actual agregando una BulkheadPolicy y una RetryPolicy personalizada. La BulkheadPolicy limitará el número de solicitudes concurrentes, mientras que la RetryPolicy reintentará solo la solicitud fallida en lugar de todas las solicitudes fallidas.

    var retry = Policy.Handle<httprequestexception>()
        .RetryAsync(1, onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Reintento {retryCount}...");
        });
    
    var bulk = Policy.BulkheadAsync(1);
    
    builder.Services.AddHttpClient<testclient>()
        .AddPolicyHandler(retry)
        .AddPolicyHandler(bulk);
    

    En el código anterior, hemos creado una política retry personalizada que reintentará solo una vez y registrará el número de reintentos. También hemos agregado una BulkheadPolicy con un límite de concurrencia de 1.

    Ahora, cuando una solicitud falla, la BulkheadPolicy limitará el número de solicitudes concurrentes y la política retry reintentará solo la solicitud fallida. Si el reintento es exitoso, se reanudará el flujo normal y se enviarán las solicitudes restantes.

    Esta implementación garantizará que el servidor no se sobrecargue con un gran número de solicitud

Comments are closed.