-
Notifications
You must be signed in to change notification settings - Fork 11
Resilience
Requests can end with errors for many reasons, so it is necessary to ensure resilience. By default, a request is executed once without retries. If the request ended with an unsuccessful HTTP status code and the returned method value is not HTTP response, an exception will be thrown. To change the logic of retries, you can use the WithResilience methods.
Use the WithFullResilience method to retry requests for any methods:
IMyClient myClient = NClientGallery.Clients.GetRest()
.For<IMyClient>(host: "http://localhost:8080")
.WithFullResilience(
maxRetries: 4,
getDelay: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
shouldRetry: responseContext => !responseContext.Response.IsSuccessStatusCode)
.Build();The parameters maxRetries, getDelay and shouldRetry are optional. By default, 3 attempts are used with a quadratic increase in the delay between attempts for responses with unsuccessful codes.
To use retries for safe methods (GET, HEAD, OPTIONS), use the WithSafeResilience method. To use retries for all methods except POST, use the WithIdempotentResilience method.
Set specific resilience policy for a method using the WithResilience method:
IMyClient myClient = NClientGallery.Clients.GetRest()
.For<IMyClient>(host: "http://localhost:8080")
.WithResilience(builder => builder
.ForMethod(client => ((Func<Entity, Task>)x.PostAsync).Use(maxRetries: 4))
.Build();You can flexibly configure resilience using a combination of policies:
IMyClient myClient = NClientGallery.Clients.GetRest()
.For<IMyClient>(host: "http://localhost:8080")
.WithFullResilience(maxRetries: 4)
.WithResilience(builder => builder
.ForMethod(client => ((Func<Entity, Task>)x.PostAsync).DoNotUse())
.Build();For more complex cases, you can use the Polly library:
var retryPolicy = Policy<ResponseContext>
.HandleResult(x => !x.HttpResponse.IsSuccessful)
.Or<Exception>()
.WaitAndRetryAsync(
retryCount: 2,
sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));
IMyClient myClient = NClientGallery.Clients.GetRest()
.For<IMyClient>(host: "http://localhost:8080")
.WithResilience(builder => builder
.ForAllMethods().UsePolly(retryPolicy))
.Build();You can also create your own implementation of the IResiliencePolicyProvider and pass it to the Use method.
You may need to set policies in runtime. To create or change a policy for an already created client use the Invoke method:
public class MyResiliencePolicyProvider : IResiliencePolicyProvider { ... }
...
await myClient.AsResilient().Invoke(x => x.PostAsync(id), new MyResiliencePolicyProvider());Please note, the client interface must inherit the INClient interface.