Skip to content

The main goal of this library is to provide unified http request resilient policies for the HttpClient that just works

License

Notifications You must be signed in to change notification settings

NYMEZIDE/httpclient-resilience-policies

 
 

Repository files navigation

Dodo.HttpClient.ResiliencePolicies library

nuget master

The main goal of this library is to provide unified http request retrying policies for the HttpClient that just works.

Actually this library wraps awesome Polly library with the predefined settings to allow developers to use it as is without a deep dive to Polly.

The DefaultPolicy provided by this library combines RetryPolicy, CircuitBreakerPolicy and TimeoutPolicy under the hood. See the corresponding sections of the README.

Functionality provided by the library

Library provides few methods which returns the IHttpClientBuilder and you may chain it with other HttpMessageHandler.

There are list of public methods to use:

// Default policies for a single host environment using all defaults
IHttpClientBuilder AddDefaultPolicies(this IHttpClientBuilder clientBuilder);

// Default policies for a single host environment with custom settings
IHttpClientBuilder AddDefaultPolicies(this IHttpClientBuilder clientBuilder, HttpClientSettings settings);

// Default policies for a multi host environments using all defaults
IHttpClientBuilder AddDefaultHostSpecificPolicies(this IHttpClientBuilder clientBuilder);

// Default policies for a multi host environments with custom settings
IHttpClientBuilder AddDefaultHostSpecificPolicies(this IHttpClientBuilder clientBuilder, HttpClientSettings settings);

// Default JsonClient includes DefaultPolicies with custom settings
IHttpClientBuilder AddJsonClient<TClientInterface, TClientImplementation>(
    this IServiceCollection sc,
    Uri baseAddress,
    HttpClientSettings settings,
    string clientName = null)
        where TClientInterface : class
        where TClientImplementation : class, TClientInterface

There are also available HttpClientSettings, IRetrySettings and ICircuitBreakerSettings to tune-in the default policies. See the corresponding sections of the README.

HttpClient configuration

You have two options how to add HttpClient in your code.

  1. Just use default client provided by the library and add it to the ServiceCollection in the Startup like this:

    service                     // IServiceCollection
        .AddJsonClient(...)     // Default client with policies
  2. You may add your own HttpClient and then add default policies. In this case it is important to configure Timeout property in the client:

    service                     // IServiceCollection
        .AddHttpClient("named-client",
            client =>
            {
                client.Timeout = TimeSpan.FromMilliseconds(Defaults.Timeout.HttpClientTimeoutInMilliseconds); // Constant provided by the library
            })
        .AddDefaultPolicies()   // Default policies provided by the library

Or if you use custom HttpClientSettings you may get client timeout value from the HttpClientSettings.HttpClientTimeout property instead of constant.

Configure HttpClient.Timeout is important because HttpClient will use default value of 100 seconds without this configuration. AddJsonClient provided by the library is already pre-configured.

More details about TimeoutPolicy in the corresponding section of the README.

Single host versus multi host environments

You may notice that there are two group of methods: DefaultPolicy for single host environment and DefaultHostSpecificPolicy for multi host environments.

The single host environment means that our HttpClient send requests to a single host (the uri of host is never changed). It also means that if the CircuitBreaker will be opened, all requests to this host will be stopped for the duration of break.

In the other hand in multi host environment we suppose that we use single client against multiple hosts. For example in the "country agnostic service" scenario when we use a single HttpClient to send requests against the several host for different countries with the same URL pattern like: ru-host, us-host, ng-host, etc. We can't use DefaultPolicy as with single host environment scenario. If the CircuitBreaker will be opened on the one host, ex. ru-host, all requests to all other hosts will be stopped too, because of the single HttpClient. DefaultHostSpecificPolicy handles this situation by "memorizing" the distinct hosts and policies will match requests to the specific hosts to avoid such situations.

Retry policy

The retry policy handles the situation when the http request fails because of transient error and retries the attempt to complete the request.

The library provides interface IRetrySettings to setup retry policy. There are two predefined implementations provided:

  • SimpleRetrySettings which by default using Exponential backoff exponentially increase retry times for each attempt.
  • JitterRetrySettings (used by default) which is exponential too but used JitterBackoff to slightly modify retry times to prevent the situation when all of the requests will be attempt in the same time.

The most important parameter in the retry policy is RetryCount which means each request may have at most RetryCount + 1 attempts: initial request and all the retries in case of fail.

You also may implement your own policy settings by implement the IRetrySettings. Also you may check the default values in the Defaults class.

CircuitBreaker Policy

Circuit breaker's goal is to prevent requests to the server if it doesn't answer for a while to mostly of the requests. In practice the reason to have a circuit breaker is to prevent requests when server is down or overloaded.

CircuitBreaker has several important parameters:

  • FailureThreshold means what percentage of failed requests should be for the CircuitBreaker to open.
  • MinimumThroughput the minimum amount of the requests should be for the CircuitBreaker to open.
  • DurationOfBreak amount of time when the CircuitBreaker prevents all the requests to the host.
  • SamplingDuration during this amount of time CircuitBreaker will count success/failed requests and check two parameters above to make a decision should it opens or not.

More information about Circuit Breakers in the Polly documentation.

The library provides interface ICircuitBreakerSettings to setup circuit breaker policy and default implementation CircuitBreakerSettings which has a several constructors to tune-in parameters above.

You also may implement your own policy settings by implement the ICircuitBreakerSettings. Also you may check the default values in the Defaults class.

Timeout policy

The timeout policy cancels requests in case of long responses (server doesn't response for a long time).

There are only two settings to configure the timeouts:

  • HttpClientTimeout which set the timeout to the whole HttpClient.
  • TimeoutPerTry which set the timeout for a single request attempt.

Understanding of the difference between this two parameters is very important to create robust policies.

HttpClientTimeout is set to the whole HttpClient. Actually it set HttpClient.Timeout property. When this timeout exceeded the HttpClient throws TaskCancelledException which prevent all requests in the current session. Such a timeout will not be retried even if not all retry attempts have been made.

TimeoutPerTry just setup the timeout for a single request. If this timeout exceeded request will be cancelled and retried even if the server worked correctly and finally response with 200 status code.

Notice that the HttpClientTimeout should be greater than TimeoutPerRetry otherwise you requests will never be retried.

One more important thing is the order of the policies. TimeoutPolicy should always be after the RetryPolicy otherwise the TimeoutPerRetry parameter will play the same role as a HttpClientTimeout. Clarification from the Polly documentation.

You may setup your own timeout parameters by providing it to the HttpClientSettings constructor. Also you may check the default values in the Defaults class.

About

The main goal of this library is to provide unified http request resilient policies for the HttpClient that just works

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C# 100.0%