-
-
Save jzabroski/43d1a9cdad80fbb30bf429d09e1d5504 to your computer and use it in GitHub Desktop.
Example of Polly retry policy on gRPC client
This file contains hidden or 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 DemoGrpc.Domain.Entities; | |
using DemoGrpc.Protobufs; | |
using Grpc.Core; | |
using Microsoft.Extensions.DependencyInjection; | |
using Polly; | |
using System; | |
using System.Linq; | |
using System.Net.Http; | |
using System.Threading.Tasks; | |
using static DemoGrpc.Protobufs.CountryService; | |
using System.Net; | |
using Microsoft.Extensions.Logging; | |
namespace ConsoleAppGRPC | |
{ | |
class Program | |
{ | |
static async Task Main(string[] args) | |
{ | |
// DI | |
var services = new ServiceCollection(); | |
var loggerFactory = LoggerFactory.Create(logging => | |
{ | |
logging.AddConsole(); | |
logging.SetMinimumLevel(LogLevel.Debug); | |
}); | |
var serverErrors = new HttpStatusCode[] { | |
HttpStatusCode.BadGateway, | |
HttpStatusCode.GatewayTimeout, | |
HttpStatusCode.ServiceUnavailable, | |
HttpStatusCode.InternalServerError, | |
HttpStatusCode.TooManyRequests, | |
HttpStatusCode.RequestTimeout | |
}; | |
var gRpcErrors = new StatusCode[] { | |
StatusCode.DeadlineExceeded, | |
StatusCode.Internal, | |
StatusCode.NotFound, | |
StatusCode.ResourceExhausted, | |
StatusCode.Unavailable, | |
StatusCode.Unknown | |
}; | |
Func<HttpRequestMessage, IAsyncPolicy<HttpResponseMessage>> retryFunc = (request) => | |
{ | |
return Policy.HandleResult<HttpResponseMessage>(r => { | |
var grpcStatus = StatusManager.GetStatusCode(r); | |
var httpStatusCode = r.StatusCode; | |
return (grpcStatus == null && serverErrors.Contains(httpStatusCode)) || // if the server send an error before gRPC pipeline | |
(httpStatusCode == HttpStatusCode.OK && gRpcErrors.Contains(grpcStatus.Value)); // if gRPC pipeline handled the request (gRPC always answers OK) | |
}) | |
.WaitAndRetryAsync(3, (input) => TimeSpan.FromSeconds(3 + input), (result, timeSpan, retryCount, context) => | |
{ | |
var grpcStatus = StatusManager.GetStatusCode(result.Result); | |
Console.WriteLine($"Request failed with {grpcStatus}. Retry"); | |
}); | |
}; | |
services.AddGrpcClient<CountryServiceClient>(o => | |
{ | |
o.Address = new Uri("https://localhost:5001"); | |
}).AddPolicyHandler(retryFunc); | |
var provider = services.BuildServiceProvider(); | |
var client = provider.GetRequiredService<CountryServiceClient>(); | |
try | |
{ | |
var countries = (await client.GetAllAsync(new EmptyRequest())).Countries.Select(x => new Country | |
{ | |
CountryId = x.Id, | |
Description = x.Description, | |
CountryName = x.Name | |
}).ToList(); | |
Console.WriteLine("Found countries"); | |
countries.ForEach(x => Console.WriteLine($"Found country {x.CountryName} ({x.CountryId}) {x.Description}")); | |
} | |
catch (RpcException e) | |
{ | |
Console.WriteLine(e.Message); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment