AYUDA .NET

Polly Retry (Cómo funciona para los desarrolladores)

Actualizado 6 de junio, 2024
Compartir:

Gestionar los fallos transitorios, los tiempos de espera y las excepciones con elegancia es crucial para crear aplicaciones robustas y resistentes. Polly es una popular librería .NET que proporciona capacidades de resiliencia y gestión de fallos transitorios. Entre sus muchas funciones, "reintentar" es una de las políticas más utilizadas.

En este artículo, profundizaremos en Política de reintentos de Polly en C# y las opciones de configuración, así como ejemplos prácticos de código. Además, utilizaremos IronPDF con el intento de Polly Retry para generar un PDF con los resultados de la solicitud del formulario.

¿Qué es Polly Retry?

Polly Retry es una política proporcionada por la librería Polly que permite a los desarrolladores reintentar automáticamente operaciones que puedan fallar debido a un error o fallos transitorios. Los fallos transitorios son errores temporales que se producen debido a fallos de la red, indisponibilidad del servicio u otros problemas transitorios.

Con la política de reintentos de Polly, puede definir reglas para reintentar operaciones, incluido el número máximo de reintentos, el retraso entre varios reintentos y las condiciones para reintentar una solicitud fallida. Esto ayuda a crear aplicaciones resistentes que pueden recuperarse de fallos temporales sin bloquearse ni causar interrupciones a los usuarios finales.

Primeros pasos con Polly Retry

Antes de sumergirnos en los ejemplos de código, vamos a establecer una comprensión básica de cómo instalar y configurar Polly en un proyecto C#.

Instalación de Polly

Puede instalar Polly a través de la Consola del Gestor de Paquetes NuGet utilizando el siguiente comando:

Install-Package Polly
Install-Package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'Install-Package Polly
VB   C#

O a través de .NET CLI:

dotnet add package Polly
dotnet add package Polly
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'dotnet add package Polly
VB   C#

Añadir Polly mediante declaraciones

En su archivo C#, incluya el espacio de nombres Polly:

using Polly;
using Polly;
Imports Polly
VB   C#

Ejemplo de política básica de reintentos

Empecemos con un ejemplo sencillo en el que reintentamos una operación que simula la obtención de datos de un servicio remoto. Configuraremos una política de reintentos con un máximo de 3 reintentos y un tiempo de espera fijo de 2 segundos entre reintentos.

using System;
using System.Net.Http;
using Polly;
namespace PollyRetryExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
           var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetry(
                    3,
                    retryAttempt => TimeSpan.FromSeconds(2),
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });
            try
            {
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }
        public static void FetchDataFromRemoteService()
        {
            throw new HttpRequestException("Failed to fetch data from remote service");
        }
    }
}
using System;
using System.Net.Http;
using Polly;
namespace PollyRetryExample
{
    public class Program
    {
        public static void Main(string[] args)
        {
           var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetry(
                    3,
                    retryAttempt => TimeSpan.FromSeconds(2),
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message);
                    });
            try
            {
                retryPolicy.Execute(() =>
                {
                    FetchDataFromRemoteService();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed after 3 retries: {0}", ex.Message);
            }
        }
        public static void FetchDataFromRemoteService()
        {
            throw new HttpRequestException("Failed to fetch data from remote service");
        }
    }
}
Imports System
Imports System.Net.Http
Imports Polly
Namespace PollyRetryExample
	Public Class Program
		Public Shared Sub Main(ByVal args() As String)
		   Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(3, Function(retryAttempt) TimeSpan.FromSeconds(2), Sub(exception, timeSpan, retryCount, context)
			   Console.WriteLine("Retry {0} due to {1}", retryCount, exception.Message)
		   End Sub)
			Try
				retryPolicy.Execute(Sub()
					FetchDataFromRemoteService()
				End Sub)
			Catch ex As Exception
				Console.WriteLine("Failed after 3 retries: {0}", ex.Message)
			End Try
		End Sub
		Public Shared Sub FetchDataFromRemoteService()
			Throw New HttpRequestException("Failed to fetch data from remote service")
		End Sub
	End Class
End Namespace
VB   C#

En este ejemplo:

  • Mango()especifica que queremos manejar una HttpRequestException y reintentar la operación si ocurre.
  • EsperarYRetener() configura la política de reintentos con 3 reintentos y un retardo fijo de 2 segundos entre reintentos. (duración máxima especificada).
  • el delegado onRetry registra un mensaje cuando se produce un reintento.

    Polly Retry (Cómo funciona para los desarrolladores): Figura 1

Configuración avanzada de la política de reintentos

Retroceso exponencial

El backoff exponencial es una popular estrategia de reintentos en la que el retardo entre peticiones y reintentos aumenta exponencialmente. Polly proporciona una manera conveniente de implementar el backoff exponencial usando WaitAndRetry().

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(retryCount:= 3, sleepDurationProvider:= Function(attempt) TimeSpan.FromSeconds(Math.Pow(2, attempt)), onRetry:= Sub(exception, retryCount, context)
	Console.WriteLine($"Retry {retryCount} due to {exception.Message}")
End Sub)
VB   C#

Polly Retry (Cómo funciona para los desarrolladores): Figura 2

Reintento con disyuntor

Combinar el reintento con un disyuntor puede mejorar aún más la resiliencia al evitar repetidos reintentos cuando un servicio falla constantemente. Polly le permite combinar fácilmente las políticas de reintento y de disyuntor.

var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3,
        durationOfBreak: TimeSpan.FromSeconds(30),
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
var circuitBreakerPolicy = Policy
    .Handle<HttpRequestException>()
    .CircuitBreaker(
        exceptionsAllowedBeforeBreaking: 3,
        durationOfBreak: TimeSpan.FromSeconds(30),
        onBreak: (ex, breakDelay) =>
        {
            Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.");
        },
        onReset: () =>
        {
            Console.WriteLine("Circuit reset.");
        });
var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetry(
        retryCount: 3,
        sleepDurationProvider: attempt => TimeSpan.FromSeconds(2),
        onRetry: (exception, retryCount, context) =>
        {
            Console.WriteLine($"Retry {retryCount} due to {exception.Message}");
        });
var policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy);
Dim circuitBreakerPolicy = Policy.Handle(Of HttpRequestException)().CircuitBreaker(exceptionsAllowedBeforeBreaking:= 3, durationOfBreak:= TimeSpan.FromSeconds(30), onBreak:= Sub(ex, breakDelay)
			Console.WriteLine($"Circuit broken due to {ex.Message}. Retry after {breakDelay.TotalSeconds} seconds.")
End Sub, onReset:= Sub()
			Console.WriteLine("Circuit reset.")
End Sub)
Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetry(retryCount:= 3, sleepDurationProvider:= Function(attempt) TimeSpan.FromSeconds(2), onRetry:= Sub(exception, retryCount, context)
	Console.WriteLine($"Retry {retryCount} due to {exception.Message}")
End Sub)
Dim policyWrap = Policy.Wrap(circuitBreakerPolicy, retryPolicy)
VB   C#

En este ejemplo:

  • Disyuntor()` define una política de disyuntor que se rompe después de 3 excepciones y permanece abierto durante 30 segundos.
  • Política.Wrap() combina las políticas de interrupción y reintento en una única política.

    Polly Retry (Cómo funciona para los desarrolladores): Figura 3

Introducción a IronPDF

IronPDF para C# es una potente biblioteca C# que permite a los desarrolladores crear, editar y manipular documentos PDF dentro de sus aplicaciones .NET. Tanto si necesita crear facturas, informes o cualquier otro tipo de documento PDF, IronPDF proporciona una API intuitiva que simplifica el proceso.

Con IronPDF, puede convertir fácilmente páginas web HTML, CSS e incluso ASP.NET a PDF, lo que la convierte en una herramienta versátil para una amplia gama de aplicaciones. Además, ofrece funciones avanzadas como añadir texto, imágenes y elementos interactivos a los PDF, así como protegerlos con cifrado y firmas digitales.

Polly Retry con IronPDF

Al trabajar con IronPDF, puede haber situaciones en las que necesite obtener datos de fuentes externas o realizar operaciones complejas antes de generar un PDF.

En estos casos, es posible que se produzcan fallos transitorios o problemas temporales que podrían provocar fallos en la generación de PDF. Para gestionar estos fallos transitorios con elegancia, puede utilizar Polly Retry junto con IronPDF.

Instalación de IronPDF y Polly

Antes de empezar, asegúrese de instalar el paquete IronPDF NuGet en su proyecto.

Install-Package IronPdf

Uso de Polly Retry con IronPDF

Veamos un ejemplo en el que utilizamos Polly Retry para gestionar fallos transitorios al generar un PDF utilizando IronPDF. En el siguiente ejemplo, simularemos la obtención de datos de una API externa y la posterior generación de un PDF basado en esos datos. Utilizaremos Polly Retry para ejecutar la operación de obtención de datos en caso de fallos.

using System;
using System.Net.Http;
using System.Threading.Tasks;
using IronPdf;
using Polly;
namespace IronPdfWithPollyRetry
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetryAsync(
                    3,//intentos de reintento
                    retryAttempt => TimeSpan.FromSeconds(2),//retardo de reintento calculado
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync();
                return GeneratePdfFromData(data);
            });
            pdf.SaveAs("GeneratedDocument.pdf");
        }
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            //  Simular la obtención de datos de una API externa
            await Task.Delay(100); //  Simular retraso
            throw new HttpRequestException("Failed to fetch data from external API");
        }
        static PdfDocument GeneratePdfFromData(string data)
        {
            //  Generación de PDF con IronPDF a partir de los datos obtenidos
            var htmlContent = "<html><body><h1>Data: " + data + "</h1></body></html>";
            var renderer = new ChromePdfRenderer();
            return renderer.RenderHtmlAsPdf(htmlContent);
        }
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using IronPdf;
using Polly;
namespace IronPdfWithPollyRetry
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .WaitAndRetryAsync(
                    3,//intentos de reintento
                    retryAttempt => TimeSpan.FromSeconds(2),//retardo de reintento calculado
                    (exception, timeSpan, retryCount, context) =>
                    {
                        Console.WriteLine("Retry " + retryCount + " due to " + exception.Message);
                    });
            var pdf = await retryPolicy.ExecuteAsync(async () =>
            {
                var data = await FetchDataFromExternalApiAsync();
                return GeneratePdfFromData(data);
            });
            pdf.SaveAs("GeneratedDocument.pdf");
        }
        static async Task<string> FetchDataFromExternalApiAsync()
        {
            //  Simular la obtención de datos de una API externa
            await Task.Delay(100); //  Simular retraso
            throw new HttpRequestException("Failed to fetch data from external API");
        }
        static PdfDocument GeneratePdfFromData(string data)
        {
            //  Generación de PDF con IronPDF a partir de los datos obtenidos
            var htmlContent = "<html><body><h1>Data: " + data + "</h1></body></html>";
            var renderer = new ChromePdfRenderer();
            return renderer.RenderHtmlAsPdf(htmlContent);
        }
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports IronPdf
Imports Polly
Namespace IronPdfWithPollyRetry
	Public Class Program
		Public Shared Async Function Main(ByVal args() As String) As Task
			Dim retryPolicy = Policy.Handle(Of HttpRequestException)().WaitAndRetryAsync(3, Function(retryAttempt) TimeSpan.FromSeconds(2), Sub(exception, timeSpan, retryCount, context)
				Console.WriteLine("Retry " & retryCount & " due to " & exception.Message)
			End Sub)
			Dim pdf = Await retryPolicy.ExecuteAsync(Async Function()
				Dim data = Await FetchDataFromExternalApiAsync()
				Return GeneratePdfFromData(data)
			End Function)
			pdf.SaveAs("GeneratedDocument.pdf")
		End Function
		Private Shared Async Function FetchDataFromExternalApiAsync() As Task(Of String)
			'  Simular la obtención de datos de una API externa
			Await Task.Delay(100) '  Simular retraso
			Throw New HttpRequestException("Failed to fetch data from external API")
		End Function
		Private Shared Function GeneratePdfFromData(ByVal data As String) As PdfDocument
			'  Generación de PDF con IronPDF a partir de los datos obtenidos
			Dim htmlContent = "<html><body><h1>Data: " & data & "</h1></body></html>"
			Dim renderer = New ChromePdfRenderer()
			Return renderer.RenderHtmlAsPdf(htmlContent)
		End Function
	End Class
End Namespace
VB   C#

Este código C# demuestra cómo utilizar la biblioteca Polly para implementar políticas de reintento con IronPDF para generar un documento PDF. El método Main inicializa una política de reintentos utilizando el método WaitAndRetryAsync de Polly.

Esta política especifica que debe manejar HttpRequestException y reintentar la operación hasta 3 veces con un retardo de 2 segundos entre el intento inicial y los reintentos. Si se produce un fallo de reintento, se imprime un mensaje en la consola indicando el número de intento de reintento y el mensaje de excepción.

Dentro del método Main, la lógica de la política de reintentos se ejecuta de forma asíncrona utilizando retryPolicy.ExecuteAsync(). Dentro de esta ejecución, se encadenan dos operaciones asíncronas: FetchDataFromExternalApiAsync() y GeneratePdfFromData(datos).

Si FetchDataFromExternalApiAsync() falla (como está intencionadamente configurado para hacer con una excepción simulada)la política de reintento capturará la HttpRequestException, registrará el intento de reintento y reintentará la operación.

La función FetchDataFromExternalApiAsync()simula la obtención de datos de una API externa con un retraso y lanza intencionadamente unaHttpRequestException` para simular peticiones fallidas.

Polly Retry (Cómo funciona para los desarrolladores): Figura 4

Conclusión

En conclusión, la política de reintentos de Polly resulta inestimable para gestionar fallos transitorios y garantizar la robustez de las aplicaciones C#. Su flexibilidad a la hora de configurar los intentos de reintento, los retrasos y las condiciones permite a los desarrolladores adaptar las estrategias de resistencia a requisitos específicos.

Tanto si se utiliza de forma independiente como en combinación con bibliotecas como IronPDF, Polly facilita la creación de aplicaciones que se recuperan con elegancia de fallos temporales, mejorando la experiencia del usuario y la fiabilidad del software.

Al integrar las funciones de reintento de Polly, los desarrolladores pueden crear sistemas más resistentes que pueden adaptarse y recuperarse de problemas transitorios, mejorando en última instancia la calidad y fiabilidad general de sus aplicaciones.

IronPDF es la mejor librería PDF en C# del mercado, además ofrece un licencia de prueba precios a partir de $749 USD.

Para obtener más información sobre la conversión de HTML a PDF con IronPDF, visite la siguiente página web enlace.

< ANTERIOR
C# iList (Cómo funciona para desarrolladores)
SIGUIENTE >
WebClient C# (Cómo funciona para desarrolladores)

¿Listo para empezar? Versión: 2024.7 recién publicada

Descarga gratuita de NuGet Descargas totales: 9,848,088 Ver licencias >
123