.NET Resilience With Polly

12 november 2021 om 10:00 by ParTech Media - Post a comment

Applications are powerful and useful until an issue crops up suddenly to stop the happy path. For example, consider an application that performs file processing by reading a file and writing the key points as output in another file.

In .Net, the file access is done through in-built libraries that can help in reading and writing files. This provides the link between the user-written code and the file system. Under the happy path scenario, no one worries about the code that connects files and does IO operation. The memory is normally flushed once that work is done.

But in case of an error, multiple scenarios and questions come into the picture. For example -

  • Was the file closed properly (otherwise it would block the users)?
  • Did the task get executed successfully by extracting the information?

To handle these things, a ‘try, catch and a finally’ block can be introduced to close the file and throw the exceptions.

But there are chances that when we retry doing the same activity, it will succeed. And when you perform a retry attempt, a separate logic has to be written and other supporting configurations need to be maintained. The readability of the code also takes a hit.

In other words, you need a retry logic that needs to be implemented on certain exception conditions without making the code complex and without reducing the readability. The answer you are looking for is Polly, a NuGet package, which can be used with .Net applications.

In this post, we will see everything about Polly and how it can be implemented with .Net applications for achieving the retrying logic.

Table of contents

  1. What is Polly?
  2. Implementing Polly and exploring its functionalities, and
  3. Conclusion.

What is Polly?

Polly is a .Net library that provides support for resilience, fault tolerance, and handling pre-built code that makes developers' lives simpler. It does so by providing functionalities like Retry, Circuit breaker, Timeout, Bulkhead Isolation, etc. Polly library can be installed with the help of the NuGet package manager and then can be subsequently used in the code.

Implementing Polly and exploring its functionalities

To implement and explore the functionalities of Polly, we are going to create a console-based .Net Application that will be used throughout the example.

Step 1

Create a .Net 5.0 based Console application and provide a valid name to the solution.

Step 2

The default code structure looks like below. It contains a Program.cs file where the main method is present.

Step 3

The next step is to install the Polly library. Right-click on the Solution and click on ‘Manage NuGet Packages’. Now search for Polly and install the package.

Once the Polly library is successfully installed in the code, it is time for us to explore the functionalities available in it.

Retry Logic

Before we explore the retry logic, we will create a small test method that throws DivideByZeroException. This will be used to explore the functionalities of retry.

From the main method, the test method would be called. And to make use of the Retry code from Polly, Polly would be referred to in the solution header. The Policy classes present in it will be utilized for the retry purpose.

First, we are going to try the limited retry count in the event of an exception. Below is the sample code that can be used -

using Polly;
using System;
namespace PARTECH_Polly
  class Program
​    static int iteration;
​    static void Main(string[] args)
​    {
​      Console.WriteLine("Hello World!");
​      Policy.Handle<Exception>()
​          .Retry(5)
​          .Execute(TestMethod);
​      Console.ReadLine();
​    }

​    static void TestMethod()
​    {
​      iteration++;
​      var i = 0;
​      var j = 2;
​      Console.WriteLine(iteration);
​      var result = j / i;
​    }

The above code executes 5 times and reports the exception (as we have deliberately introduced one). To try it for an infinite number of times, the Policy section needs to be replaced with the below lines -

​          .RetryForever()
​          .Execute(TestMethod);

This will end up retrying until the code succeeds. Also, in case we need to keep track of the number of attempts the code has been executed, there is an in-built option to achieve the same. Here is the sample code to implement it -

​          .Retry(10, (e, i) => Console.WriteLine($"Error '{e.Message}' and the current retry count - {i}"))
​          .Execute(TestMethod);

The above code would be retried 10 times. However, it will also write the exception and the count of the retry in the console every time. This code implements the retry logic right after the exception occurs. There is also the option to Wait before the retry happens. Here is the code for that -

​          .WaitAndRetry(new[] { TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(200) })
​          .Execute(TestMethod);

The number of period entries is proportional to the retry attempts. It is also possible to dynamically configure the wait time as below.

​          .WaitAndRetry(5, count => TimeSpan.FromMilliseconds(count))
​          .Execute(TestMethod);

You can even configure wait time to run forever until it succeeds.

​         .WaitAndRetryForever(count => TimeSpan.FromMilliseconds(count))
​         .Execute(TestMethod);

The last part which is going to be discussed here is the CircuitBreaker. Similar to the real world, CircuitBreaker stops the piece of code from executing after a certain number of exceptions. It is also possible to configure the cooldown until which the code will not be executed. After this, the user process starts.

​         .CircuitBreaker(5, TimeSpan.FromMilliseconds(2000))
​         .Execute(TestMethod);

Final Words

The above-discussed points are some of the useful functionalities of the Polly library which is a plug and play package for handling faults. So use it in your next application if you need to implement retry logic.