Last active
March 8, 2024 03:57
-
-
Save pedrovasconcellos/cf2b8dcde14313e19a891408c3404337 to your computer and use it in GitHub Desktop.
Example using restsharp with polly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Polly; | |
using RestSharp; | |
using System; | |
using System.Collections.Generic; | |
using System.Net; | |
using System.Text.Encodings.Web; | |
using System.Text.Json; | |
using System.Threading.Tasks; | |
namespace RestSharpWithPolly | |
{ | |
public class HttpCommunication | |
{ | |
private static int _maxRetryAttempts = 5; | |
private static TimeSpan _pauseBetweenFailures = TimeSpan.FromSeconds(10); | |
public static void SetMaxRetryAttemptsAndPauseBetweenFailures(int maxRetryAttempts, TimeSpan pauseBetweenFailures) | |
{ | |
_maxRetryAttempts = maxRetryAttempts; | |
_pauseBetweenFailures = pauseBetweenFailures; | |
} | |
public async Task<IRestResponse> HttpAsync(Method httpVerb, string hostUrl, Dictionary<string, string> headers, object requestObject, Func<string, Task> logFunction) | |
{ | |
var restResponse = default(IRestResponse); | |
try | |
{ | |
var restRequest = new RestRequest(httpVerb); | |
restRequest.AddHeader("cache-control", "no-cache"); | |
if (headers != null && headers.Count > 0) | |
foreach (var header in headers) | |
restRequest.AddHeader(header.Key, header.Value); | |
var json = this.JsonSerialize(requestObject); | |
if(httpVerb != Method.GET) | |
{ | |
restRequest.RequestFormat = DataFormat.Json; | |
restRequest.AddParameter("application/json; charset=utf-8", json, ParameterType.RequestBody); | |
} | |
restResponse = this.RestResponseWithPolicy(new RestClient(hostUrl), restRequest, logFunction); | |
} | |
catch (Exception ex) | |
{ | |
restResponse = new RestResponse | |
{ | |
Content = ex.Message, | |
ErrorMessage = ex.Message, | |
ResponseStatus = ResponseStatus.TimedOut, | |
StatusCode = HttpStatusCode.ServiceUnavailable | |
}; | |
} | |
return await Task.FromResult(restResponse); | |
} | |
private IRestResponse RestResponseWithPolicy(RestClient restClient, RestRequest restRequest, Func<string, Task> logFunction) | |
{ | |
var retryPolicy = Policy | |
.HandleResult<IRestResponse>(x => !x.IsSuccessful) | |
.WaitAndRetry(_maxRetryAttempts, x => _pauseBetweenFailures, async (iRestResponse, timeSpan, retryCount, context) => | |
{ | |
await logFunction($"The request failed. HttpStatusCode={iRestResponse.Result.StatusCode}. Waiting {timeSpan} seconds before retry. Number attempt {retryCount}. Uri={iRestResponse.Result.ResponseUri}; RequestResponse={iRestResponse.Result.Content}"); | |
}); | |
var circuitBreakerPolicy = Policy | |
.HandleResult<IRestResponse>(x => x.StatusCode == HttpStatusCode.ServiceUnavailable) | |
.CircuitBreaker(1, TimeSpan.FromSeconds(60), onBreak: async (iRestResponse, timespan, context) => | |
{ | |
await logFunction($"Circuit went into a fault state. Reason: {iRestResponse.Result.Content}"); | |
}, | |
onReset: async (context) => | |
{ | |
await logFunction($"Circuit left the fault state."); | |
}); | |
return retryPolicy.Wrap(circuitBreakerPolicy).Execute(() => restClient.Execute(restRequest)); | |
} | |
private string JsonSerialize(object obj) => JsonSerializer.Serialize(obj, this.GetJsonSerializerOptions()); | |
private JsonSerializerOptions GetJsonSerializerOptions() => new JsonSerializerOptions | |
{ | |
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment