0

I am working on Azure Function App .net core 3.1 with Polly retry and circuit breaker. till now I dont have problem with the logging the details to App Insights using the builder because it doesnt get initialized until the execution like below

    private static void AddPoliciesAsync(this IHttpClientBuilder builder)
    {
        builder.AddPolicyHandler((service, request) =>
        GetRetryAsyncPolicy(service.GetService<ILogger<HTTPTrigger1>>()).WrapAsync(
        GetCircuitBreakerAsyncPolicy(service.GetService<ILogger<HTTPTrigger1>>())));
    }

Where HTTPTrigger1 is the function app name for testing. Now I need to extend the existing functionality to check whether the circuit is broken or not so that I can run another set of business functionalities. For that as mentioned here https://github.com/App-vNext/Polly#circuit-breaker, I have added the singleton instance of the CB to make sure am reading the circuit breaker state.

        var logger = services.BuildServiceProvider().GetService<ILogger<HTTPTrigger1>>();
        var circuitBreaker = GetCircuitBreakerAsyncPolicy(logger);
        services.AddSingleton(circuitBreaker as ICircuitBreakerPolicy<HttpResponseMessage>);
        services.AddHttpClient("name", client =>
        {
            // something
        })
        .AddPollyPolicies(logger, circuitBreaker);

But am getting the error while getting the logger instance on the second implementation. As I checked in the MS docs https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#caveats says dont log the message during the start up, eventhough am creating the instance, it still throws the error(which interns required for the subsequesnt calls). Is there anyway I can achieve the logging here?

threeleggedrabbit
  • 1,722
  • 2
  • 28
  • 60

1 Answers1

0

Why not just use the AddSingleton factory overload?

services.AddSingleton(sp => {
    var logger = sp.GetService<ILogger<HTTPTrigger1>>();
    var circuitBreaker = GetCircuitBreakerAsyncPolicy(logger);
    return circuitBreaker as ICircuitBreakerPolicy<HttpResponseMessage>;
});
Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • because, I need to get the circuitbreaker instance to used to wrap it with retry policy, services.AddHttpClient("name", client => { // something }) .AddPollyPolicies(logger, circuitBreaker); – threeleggedrabbit Apr 02 '20 at 14:52
  • This is sounding like a self-imposed injury. What is `AddPollyPolicies`, and can that be made to get the logger/circuit breaker from the service provider instead of being passed as params? – Chris Pratt Apr 02 '20 at 15:12
  • I have tried to get the logger from the service provider, but its throwing the error. var logger = services.BuildServiceProvider().GetService>(); I don't know If I will be able to get the circuit breaker policy from the service provider after registration! ? Here is what am doing in in the AddPollyPolicies => builder.AddPolicyHandler(breaker.WrapAsync(GetRetryPolicy(logger))); – threeleggedrabbit Apr 02 '20 at 15:30
  • 1
    There's an overload of `AddPolicyHandler` that uses a factory with a the service provider available. If you've registered the circuit breaker as a singleton, you'll always get the same instance. In short, all of this can be done via the factories. You don't need to actually construct it directly in Startup. – Chris Pratt Apr 02 '20 at 15:48
  • I have never tried that, will figure that out. Thanks – threeleggedrabbit Apr 02 '20 at 16:09