Polly Policies Overview
Introduction
"Resilient and Robust code with Polly in .NET Core" is a series that focuses on the usage of Polly, a .NET library that allows developers to handle faults, retry operations, and circuit-breaker patterns more efficiently and reliably.
In this series, you will learn about the different policies provided by Polly, either reactive policies to handle faults or proactive policies to prevent one. Each policy is designed to handle or prevent specific faults that may occur during an application's runtime.
With code examples written in C#, within the series you will learn how to implement each policy in your code and how to customize them to suit your application's needs. You will also learn how to handle different types of exceptions that may occur and how to react to them.
Prerequisite
Intermediate knowledge in C# generally, .NET Core specifically
Knowledge of the Retry Pattern
Visual Studio 201* or 2022
Policies Overview
As of version 7.2.3+24, there are 14 policies defined in the GitHub wiki of Polly. They are divided into reactive and proactive policies which can be used independently or as a combination of each other. The diagram below depicts an overview of all the policies available in Polly.
Retry & Retry Forever Policy
The retry policy is a resilience strategy enabling developers to specify how often a failed operation should be retried. The retry policy is useful when failures occur due to transient faults, such as network connectivity issues, and can help to increase the chances of success in subsequent attempts.
The retry forever policy is a specific type of retry policy that retries the operation indefinitely, without any upper limit on the number of retries. This policy is useful in scenarios where it's difficult to predict how many times an operation may fail before it succeeds, or when an operation needs to continue running as long as possible despite repeated failures.
Both the retry and retry forever policies can be customized with various options, such as specifying which types of exceptions should be retried, setting a maximum period for retries, or adding a jitter factor to the delay between retries to prevent all the retries from occurring at the same time.
Wait and Retry & Wait and Retry Forever Policy
The wait and retry policy is a resilience strategy that allows developers to specify a fixed delay time between retries of a failed operation. This policy is useful when the cause of failure is due to a known issue that can be resolved with time, such as a temporary system overload or server downtime.
The wait and retry forever policy is a specific type of wait and retry policy that retries the operation indefinitely, without any upper limit on the number of retries. This policy is useful in scenarios where the cause of failure is unknown, and retrying the operation with a fixed delay may eventually lead to success.
Both policies can be customized with various options, such as specifying which types of exceptions should be retried, setting a maximum period for retries, or adding a jitter factor to the delay between retries to prevent all the retries from occurring at the same time.
Circuit Breaker & Advanced Circuit Breaker Policy
The circuit breaker policy is a resilience strategy that monitors the state of a system or service and "breaks the circuit" when a certain number of failures occur within a specified time frame. When the circuit is open, subsequent calls to the service will immediately fail without attempting to execute the operation, preventing further damage to the system. After a specified period, the circuit is closed again, allowing the system to resume normal operation.
The advanced circuit breaker policy is an extension of the basic circuit breaker policy that provides more advanced features, such as different error thresholds and custom handling of circuit state changes. It also allows developers to specify a "wait and retry" period before attempting to close the circuit again, to prevent the system from becoming overwhelmed by too many requests at once.
Both policies can be customized with various options, such as setting the error threshold and time period for opening the circuit, specifying which types of exceptions should be considered failures, and configuring the wait and retry period.
Fallback Policy
The fallback policy is a resilience strategy that provides an alternative value or operation to be used when the primary operation fails. This policy is useful when a known fallback option can be used in the event of failure, such as a cached value or a default behavior.
The fallback policy allows developers to specify the fallback value or operation to be used, as well as the types of exceptions that should trigger the fallback behavior. It can be used in combination with other Polly policies, such as the retry policy or the circuit breaker policy, to create more complex resilience strategies that can handle various types of failures and errors.
The fallback policy can help to improve the resilience of an application by providing a backup plan in case of failure, reducing the impact of errors, and improving overall system reliability.
Pessimistic & Optimistic Timeout Policy
The timeout policy is a resilience strategy that limits the amount of time an operation can take to complete. If the operation exceeds the specified time limit, the policy will cancel the operation and throw a timeout exception. This can help to prevent long-running operations from blocking the application and causing performance issues.
The pessimistic timeout policy sets a fixed timeout value for each operation and cancels the operation if it exceeds that value. This policy assumes that operations are likely to take the full specified timeout period and may not complete in time.
The optimistic timeout policy in Polly sets a timeout value for each operation but allows the operation to continue running past the specified timeout if it is making progress. This policy assumes that operations are likely to complete within the specified timeout period and will only cancel the operation if no progress is being made.
Both policies can be customized with various options, such as setting the timeout value, specifying the types of exceptions that should trigger a timeout, and configuring the cancellation token source.
Bulkhead Policy
The bulkhead policy is a resilience strategy that limits the number of concurrent operations that can be executed at the same time. This policy can help to prevent overloading a system or service with too many requests and can improve overall system stability and performance.
The bulkhead policy allows developers to specify the maximum number of parallel operations that can be executed, as well as the types of exceptions that should be considered bulkhead violations. If the maximum number of concurrent operations is reached, any subsequent requests will be queued until a previous operation completes.
Rate-Limit Policy
The rate-limit policy is a resilience strategy that limits the rate at which operations can be executed. This policy can help to prevent overloading a system or service with too many requests and can improve overall system stability and performance.
The rate-limit policy allows developers to specify the maximum number of operations that can be executed within a certain time period, as well as the types of exceptions that should be considered rate-limit violations. If the maximum rate is exceeded, any subsequent requests will be delayed until the next available time slot.
Cache Policy
The cache policy is a resilience strategy that caches the results of an operation for a specified amount of time. This policy can help to improve application performance by reducing the number of calls to a resource or service, as well as reducing the latency associated with those calls.
The cache policy allows developers to specify the cache duration, the cache key, and the types of exceptions that should be cached. If a cached value exists for a given cache key, the policy will return that value instead of executing the operation. If no cached value exists or the cache has expired, the policy will execute the operation and cache the result for future use.
PolicyWrap Policy
The policyWrap policy is a way to combine multiple policies into a single policy. This policy can help to create more complex resilience strategies that can handle various types of failures and errors and allows developers to wrap multiple policies together into a single policy, with each policy being executed in sequence. This can be useful when multiple policies need to be applied to the same operation, or when a specific order of policies is required.
NoOp Policy
The NoOp (No Operation) policy is a policy that does not modify the behavior of an operation or add any resilience capabilities. This policy can be useful in certain scenarios where a placeholder policy is needed or when testing the behavior of a Polly policy pipeline.
The NoOp policy simply returns the result of the operation without executing any retry, circuit breaker, or other resilience logic. It can be used as a placeholder policy to fill in gaps in a policy pipeline or to test how a pipeline behaves when a specific policy is not present.
While the NoOp policy does not add any resilience capabilities, it can still be useful in certain situations where a placeholder or testing policy is needed.
Resilient and Robust with Multi-Policies
Combining policies in Polly allows developers to create more robust and resilient code by providing a flexible and customizable approach to handling failures and errors. Policies can be combined using the PolicyWrap policy, which allows multiple policies to be executed in sequence. For example, a combination of a retry policy, circuit breaker policy, and fallback policy could be wrapped together to create a more comprehensive resilience strategy.
Combining policies in this way can help to handle a wide range of failure scenarios, such as network errors, service downtime, or other unexpected errors. It can also help to improve the overall performance of an application by reducing the impact of failures and errors.
In addition, combining policies can make code more readable and maintainable by separating the resilience logic from the core business logic. This can make it easier to add, modify, or remove policies as needed, without affecting the underlying code.
Overall, combining policies in Polly can help to improve the resilience and robustness of an application, reduce the impact of failures and errors, and make code more readable and maintainable.
What's Next
In the next article, we will take a look at Retry & Retry Forever policy and see the implementation in C# code by creating a web API project.
Final Words
Follow my blog and stay tuned for more educational content!
Subscribe to my newsletter
Read articles from Moruling James directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Moruling James
Moruling James
I am a developer from Malaysia, 10 years experience in software development with burning passions to still learn about various technology and currently into DevSecOps