Polly and Blazor, Part 3 – Dependency Injection

Full source code available here.

This post continues to build on the two previous on using Polly with Blazor. The first was a simple example of using a Wait and Retry while updating the display as the policy retried, the second did the same but made use of the Polly Context. The Polly Context is something I have not made a lot of use of in the past, but I have a feeling that it will be very helpful with Blazor applications.

I’m keeping the examples similar, deliberately changing a single thing in each. In this post I will define the Wait and Retry Policy in the Startup, add it to the service collection and inject it into the Razor page.

One big difference to note is that I can no longer update the display from inside the OnRetry delegate of the Policy. Gone is the call to InvokeAsync(StateHasChanged) because this is dependent on the the ComponentBase.

In Startup.cs add the following, it defines the Wait and Retry policy, and its OnRetry delegate –

public void ConfigureServices(IServiceCollection services)
    {
    IAsyncPolicy<HttpResponseMessage> _httpRequestPolicy = Policy.HandleResult<HttpResponseMessage>(
    r => !r.IsSuccessStatusCode)
    .WaitAndRetryAsync(3,
        retryAttempt => TimeSpan.FromSeconds(retryAttempt), onRetry: (response, retryDelay, retryCount, context) =>
        {
            context["message"] = context["message"] + $"\nReceived: {response.Result.StatusCode}, retryCount: {retryCount}, delaying: {retryDelay.Seconds} seconds";
        });

    services.AddSingleton<IAsyncPolicy<HttpResponseMessage>>(_httpRequestPolicy);
    // snip...

In the Razor section of the Index.razor page add this –

@inject IAsyncPolicy<HttpResponseMessage> _httpRequestPolicy

The policy will now be injected into the Razor page.

Using it is simple, see line 16 below –

@code {
   HttpClient httpClient = new HttpClient() {
        BaseAddress =  new Uri("http://localhost:5000")
    };

    private string status;
    private Context context = new Polly.Context("", new Dictionary<string, object>() {{"message",""}}); 
    private string responseCode;
    private string number;

    private async Task CallRemoteServiceAsync()
    {
        status = "Calling remote service...";
        string requestEndpoint = "faulty/";

        HttpResponseMessage httpResponse = await _httpRequestPolicy.ExecuteAsync(ctx => httpClient.GetAsync(requestEndpoint), context);
        responseCode = httpResponse.StatusCode.ToString();
        number = await httpResponse.Content.ReadAsStringAsync();
        status = "Finished";
    }
}

Instead of injecting a Polly Policy you could inject a Polly Registry with more than one policy. I have written about the registry a few times on this blog.

Full source code available here.

Polly and Blazor, Part 2 – Using the Context

Full source code available here.

This post is a short follow up to the one where I used Polly Wait and Retry in Blazor. In that post I used variables defined in my C# method to pass information back to the calling code, to display on the screen. But here I’m going to show how the Polly Context can be used instead.

The setup and almost all the code is the same, so please take a look at that post.

Using the Context
The Razor section references the message in the Polly context rather than a defined variable for the message –

<p>Polly Summary : @context["message"]</p>

In the code block add a Polly Context and initialize the dictionary with a message, this is important because the Razor block references this message when the page loads.

@code {
    //snip...

    private Context context = new Polly.Context("", new Dictionary<string, object>() {{"message",""}});
    //snip... 

Then in the rest of the code block, update the message in the context with the information to display to the user.

private async Task CallRemoteServiceAsync()
{
    IAsyncPolicy<HttpResponseMessage> _httpRequestPolicy = Policy.HandleResult<HttpResponseMessage>(
        r => !r.IsSuccessStatusCode)
        .WaitAndRetryAsync(3,
            retryAttempt => TimeSpan.FromSeconds(retryAttempt * 2), onRetry: (response, retryDelay, retryCount, context) => {
                context["message"] = $"Recieved: {response.Result.StatusCode}, retryCount: {retryCount}, delaying: {retryDelay.Seconds} seconds\n";
                Console.WriteLine(context["message"]);
                InvokeAsync(StateHasChanged);
    });
    status = "Calling remote service...";
    string requestEndpoint = "faulty/";
    HttpResponseMessage httpResponse = await _httpRequestPolicy.ExecuteAsync(ctx => httpClient.GetAsync(requestEndpoint), context);
    responseCode = httpResponse.StatusCode.ToString();
    number = await httpResponse.Content.ReadAsStringAsync();
    status = "Finished";
    context["message"] = "";
}

That’s it, another way to do the same thing.

In the next post I’ll show how to use a Polly Policy defined within the OnInitializedAsync block.

Full source code available here.

Polly and Blazor, Part 1 – Simple Wait and Retry

Full source code available here.

A few weeks ago I gave a talk on Polly at Dotnetconf (you can check it out here), at the end I got many questions about using Polly with Blazor, I had never tried it, but assumed it would work.

In this blog, part 1 of a few on Polly and Blazor, I’ll show you how to get a simple retry mechanism up and working in a Blazor Server App. I am not concerned with dependency injections, policy registries or anything other fancy things in this post, that will come later..

The setup
I have a .Net 5 Blazor Server app created with

dotnet new blazorserver

I stripped out the Blazor pages I didn’t need, and changed the code of the Index.razor file to make a HTTP call to a controller that generates errors 75% of time. I removed links to the other Blazor pages too.

Around the HTTP call I use the Polly Wait and Retry Policy to retry up three times, with a delay between each request. If you haven’t used Polly before, I have written a LOT about it, and have a Pluralsight course on it.

I made a few updates to the UI to show what the HttpClient and Polly are doing.

The Wait and Retry policy will retry after 2, 4 and 6 seconds. It prints out the to the console and updates the UI with the errors it gets from the remote system and details about the retry.

Because this is my first Blazor app, it took a little longer and may have some less than perfect approaches, but you should be able to take the retry idea and apply it to you application.

Before I show the code for retrying, let me show how I added a familiar Web API controller.

In Configure(..) method of Startup.cs I added endpoints.MapControllers(); to the below block so it looks like this –

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers(); // added this
    endpoints.MapBlazorHub();
    endpoints.MapFallbackToPage("/_Host");
});

Then I created a Controllers directory and added a new file FaultyController.cs.

Here is its code –

using Microsoft.AspNetCore.Mvc;

namespace WebApiDataDog.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class FaultyController : ControllerBase
    {
        private static int counter = 0;

        public FaultyController()
        {
        }

        [HttpGet]
        public ActionResult Get()
        {
            if (++counter % 4 == 0)
            {
                return Ok(counter);
            }
            else if(counter % 4 == 1)
            {
                return StatusCode(501);
            }
            else if(counter % 4 == 2)
            {
                return StatusCode(502);
            }
            else
            {
                return StatusCode(503);
            }
        }
    }
}

And here is my Razor page that uses the Polly Wait and Retry policy.

@page "/"
@using Polly

<h1>Polly Test</h1>
<p>This demo uses a HttpClient to call a controller that is setup to fail 75% of the time (first three request will fail, fourth will succeed). The Polly Retry policy will kick in a retry up to three time.</p>

<p>Status: @status</p>
<p>Polly Summary : @pollyMessage</p>

<p>Response Code : @responseCode</p>
<p>Response Body : @number</p>

<button class="btn btn-primary" @onclick="CallRemoteServiceAsync">Call remote service</button>

@code {
   HttpClient httpClient = new HttpClient() {
        BaseAddress =  new Uri("http://localhost:5000")
    };

    private string status;
    private string pollyMessage;
    private string responseCode;
    private string number;

    private async Task CallRemoteServiceAsync()
    {
        IAsyncPolicy<HttpResponseMessage> _httpRequestPolicy = Policy.HandleResult<HttpResponseMessage>(
            r => !r.IsSuccessStatusCode)
            .WaitAndRetryAsync(3,
                retryAttempt => TimeSpan.FromSeconds(retryAttempt * 2), onRetry: (response, retryDelay, retryCount, context) => {
                    pollyMessage = $"Recieved: {response.Result.StatusCode}, retryCount: {retryCount}, delaying: {retryDelay.Seconds} seconds\n";
                    Console.WriteLine(pollyMessage);
                    InvokeAsync(StateHasChanged);
        });

        status = "Calling remote service...";
        string requestEndpoint = "faulty/";

        HttpResponseMessage httpResponse = await _httpRequestPolicy.ExecuteAsync(() => httpClient.GetAsync(requestEndpoint));
        
        responseCode = httpResponse.StatusCode.ToString();
        number = await httpResponse.Content.ReadAsStringAsync();
        status = "Finished";
        pollyMessage = "";
    }
}

As I said above, I’m going to write a few more posts on Polly and Blazor to show some other scenarios, like using the Polly Context to pass data around and dependency injection (hopefully).

Full source code available here.

Registering Multiple Implementations of an Interface in ASP.NET Core with Autofac

Full source code here.

A few weeks ago I wrote a post about using dependency injection to pick between two implementations of an interface. It was a solution I was not very happy with because it meant I had to new up the implementations inside a factory or I had to use service collection to instantiate all implementations of the interface and then use a piece of code to return the one the was wanted.

As of this writing service collection does not natively support choosing between two implementations of a interface, but Autofac does and it can be used in place of service collection, or alongside it.

In this post I’m going to show its use alongside the service collection just for the dependencies that have multiple implementations, I’ll use service collection for dependencies that have a single collections. The examples are for ASP.NET Web Api Core 2.x and Core 3; there are small variations in how to use Autofac in those two versions of Core.

The Scenario
I have three controllers, the NegativeValuesController and PositiveValuesController take the same IValuesService and the third controller ProductsController takes an IProductsService.

The NegativeValuesController should get a NegativeValuesService and the PositiveValuesController should get a PositiveValuesService.

I’m going to use Autofac to provide the dependency injection for these controllers.

The ProductsController will use the built in ServiceCollection to fulfill its dependency.

Core 2.x
Start by adding the Autofac.Extensions.DependencyInjection package to the application.

Inside Program.cs add add .ConfigureServices(services => services.AddAutofac()) to the CreateWebHostBuilder statement.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
	WebHost.CreateDefaultBuilder(args)
	.ConfigureServices(services => services.AddAutofac())
	.UseStartup<Startup>();

In Startup.cs add this to the ConfigureServices(..) method –

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
	 .AddControllersAsServices(); // these two lines have to come before  
services.AddScoped<IProductsService, ProductsService>(); // you populte the builder a below

var builder = new ContainerBuilder();
builder.Populate(services);

builder.RegisterType<NegativeValuesService>().As<IValuesService>().AsSelf();
builder.RegisterType<PositiveValuesService>().As<IValuesService>().AsSelf();
builder.Register(ctx => new NegativeValuesController(ctx.Resolve<NegativeValuesService>()));
builder.Register(ctx => new PositiveValuesController(ctx.Resolve<PositiveValuesService>()));

AutofacContainer = builder.Build();

return new AutofacServiceProvider(AutofacContainer);

The controllers work in the normal, familar way –

public NegativeValuesController(IValuesService valuesService)
{
    _valuesService = valuesService;
}
public PositiveValuesController(IValuesService valuesService)
{
    _valuesService = valuesService;
}

That’s it, you can now choose the implementation you want for a controller.

Core 3
If you want to the same in Core 3, there are few small differences.

As before, start by adding the Autofac.Extensions.DependencyInjection package to the application.

In Program.cs add .UseServiceProviderFactory(new AutofacServiceProviderFactory()) to the CreateWebHostBuilder statement.

Back in Startup.cs add this method –

public void ConfigureContainer(ContainerBuilder builder)
{
    builder.RegisterType<NegativeValuesService>().As<IValuesService>().AsSelf();
    builder.RegisterType<PositiveValuesService>().As<IValuesService>().AsSelf();

    builder.Register(ctx => new NegativeValuesController(ctx.Resolve<NegativeValuesService>()));
    builder.Register(ctx => new PositiveValuesController(ctx.Resolve<PositiveValuesService>()));
}

Edit the ConfigureServices method to include the following –

public void ConfigureServices(IServiceCollection services)
{
	//snip..
	services.AddScoped<IProductsService, ProductsService>();

	services.AddControllers();
	services.AddMvc().AddControllersAsServices();
}

The usage inside the controllers does not change.

There you go, injecting multiple implementations of a interface in ASP.NET Core 2 and 3.

Full source code here.

Simmy Chaos Engine for .NET – Part 4, Doing Some Real Damage, Dropping a Table

Full source code here.

Up until now the Simmy examples I’ve written have thrown exceptions, changed successes to failures or slowed down a request. None of these did any real damage to your system, and your application would probably have recovered when the next request came along.

But what about dropping a table? Poof, all the data is gone. Now what does your application do?

Doing this is very easy with the Behavior clause. Like the other clauses it takes a probability, an enabled flag, and action or func that executes any piece of code.

The Scenario
I have Web API application with a products controller that queries the database for a list of products.

During application start up the database is created and populated in Configure method of Startup.cs using the EnsureCreated() method and custom seed class.

Inside the controller the action method uses the SalesContext to query the database.

Inside the controller’s constructor I have the chaos policy, it is set to drop the Products table. The drop action of the behavior policy will execute 25% of the time the policy is run. If get an error when you run this saying that the table is absent, it means the chaos policy dropped the table, you’ll have to restart the application to run through the database seeding and creation again.

The policy looks like this –

public ProductsController(SalesContext salesContext)
{
	_behaviorPolicy = MonkeyPolicy.InjectBehaviourAsync(
		 async () =>
		 {
			 await _salesContext.Database.ExecuteSqlCommandAsync("DROP TABLE Products");
			 Console.WriteLine("Dropped the Products table.");
		 },
		 0.25, // 25% of the time this policy will execute
		async () => await Task.FromResult(true));
	_salesContext = salesContext;
}

The request to the _salesContext is made inside the policy, but the policy executes before the call the db is made and in 25% of such calls the table will be dropped.

[HttpGet]
public async Task<ActionResult> Get()
{
	List<Product> products =  await _behaviorPolicy.ExecuteAsync(async () => await _salesContext.Products.Take(10).ToListAsync());

	return Ok(products);
}

You can of course execute and code from inside the policy, wipe a cache, kill a service, delete a file, etc.

This example might be a little excessive in the damage it does, you can decide if it is unreasonable to expect you application to continue working even when the database is unavailable.

Full source code here.

Registering Multiple Implementations of an Interface with Service Collection in ASP.NET Core

Full source code here.

This is a simplistic approach to the problem and assumes that the dependencies created by the factory do not in turn have their own dependencies. This deficiency could be mediated by passing those dependencies into the factory. Having said that it will be of use in some scenarios. I will publish a post in the future providing a better solution.

In a later post I will show how to use Autofac to do this properly.

The out-of-the-box dependency injection container provided by Microsoft as part of ASP.NET Core is fine for most scenarios, only in a few complicated cases have I needed to switch to Castle or AutoFac.

But there is one somewhat common case where the ServiceCollection feels a little deficient. There are times when you might have more than one implementation of an interface and you would like to choose between them at runtime.

There is no obvious way to do this.

You could try something like –

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<IValuesService, PositiveValuesService>();
            services.AddScoped<IValuesService, NegativeValuesService>();
	//snip...

But when you request an implementation of IValuesService in the constructor of a controller, the service collection will return the last registered service, in this case it will always return the NegativeValuesService.

But what if you wanted the PositiveValuesService in some controllers and the NegativeValuesService in other controllers. What if you needed to choose the service implementation based on the address of the request that the controller is handling.

Something like this –
localhost:5000/NegativeValues – should use the NegativeValuesService.
localhost:5000/PositiveValues – should use the PositiveValuesService.

Using a Factory
Instead of registering two implementations of the IValuesService, I’m going to create a ValuesServiceFactory that returns the right service based on the path of the request.

The ValuesServiceFactory has a method that looks like this –

public IValuesService GetValuesService()
{
    string path = _httpContextAccessor.HttpContext.Request.Path.Value.ToString().Trim('/').ToLower();
    switch (path)
    {
        case "positivevalues":
            return new PositiveValuesService(); // as mentioned above this only works if the values services have no dependencies
        case "negativevalues":
            return new NegativeValuesService();
        default:
            return new PositiveValuesService();
    }
}

_httpContextAccessor is what lets me access the Request from inside the factory.

A few weeks ago I wrote about post about accessing the HttpRequest from inside the constructor of a controller or from the constructor of a service the controller depends on.

That post had a contrived example, but this post has a more practical use of the technique.

The constructor of the ValuesServiceFactory needs to take an IHttpContextAccessor.

public ValuesServiceFactory(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
}

Back in Startup.cs, remove the code registering the two services and replace with a line to register the factory and the HttpContextAccessor.

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IValuesServiceFactory, ValuesServiceFactory>();
    services.AddHttpContextAccessor();
    //snip…
}

The controllers now take the implementation of IValuesServiceFactory and request the an IValuesService from the factory.

private readonly IValuesService _valuesService;

public NegativeValuesController(IValuesServiceFactory valuesServiceFactory)
{
    _valuesService = valuesServiceFactory.GetValuesService();
}

Do the same in the other controller –

private readonly IValuesService _valuesService;

public PositiveValuesController(IValuesServiceFactory valuesServiceFactory)
{
    _valuesService = valuesServiceFactory.GetValuesService();
}

That’s it, now you can choose between implementation of an interface. As I was working on this post I came across a post by Steve Gordon on this topic, he solves the same problem in a different way.

Full source code here.

Accessing the HttpContext from the Constructor of a Controller or a Dependency

Full source code here.

There are times when you may need to access the HttpRequest from places that it is not normally available such as the constructor of a controller or the constructor of a service that is built by dependency injection.

Take the example of a ValuesController that relies on a NumberGeneratorService, where both need to know the Host used in the request.

But you can’t just access the Host via the Request in either case. It is not yet available in the lifetime of the controller and it will not be available at all in the life of the service. (By the time you reach the action method of the controller you will have access to it.)

Fortunately there is a way to get at it using the HttpContextAccessor.

In Startup.cs add the following –

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<INumberGeneratorService, NumberGeneratorService>();
    services.AddHttpContextAccessor();
    //snip..
}

Pass IHttpContextAccessor to the constructor of the ValuesController

public ValuesController(IHttpContextAccessor httpContextAccessor, INumberGeneratorService numberGeneratorService)
{
    _numberGeneratorService = numberGeneratorService;
    Console.WriteLine($"Request.Host inside constructor of controller : {httpContextAccessor.HttpContext.Request.Host.Value}");
}

Do the same to the constructor of the the NumberGeneratorService

public NumberGeneratorService(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
    Console.WriteLine($"Request.Host inside service : {httpContextAccessor.HttpContext.Request.Host.Value}");
}

Now you have full access to everything about the request in controller’s constructor and the services you depend on.

In another post I’ll show a more practical use of this when I want to use the dependency injection with two implementations of an interface, HttpContextAccessor will help me choose between them based on the request.

Full source code here.

Simmy Chaos Engine for .NET – Part 3, Adding Latency

Full source code here.

This is the third in my series on chaos engineering with Simmy. The first two posts dealt with the fault policy throwing exceptions and returning failed responses rather than calling the remote service.

In this I will show how to use the latency policy to inject delays into requests. It works in a similar way to the fault policy – a delay is chosen, the percentage of the time the delay should apply is chosen, and finally the policy is enabled/disabled.

When the policy is active, it delays the request, not the response.

var latencyPolicy = MonkeyPolicy.InjectLatencyAsync<HttpResponseMessage>(
    TimeSpan.FromSeconds(5), // inject a 5 second delay
    0.5, // in 50% of requests
    () => true); // policy is enabled

To see the effect of the latency policy I am going to add Polly timeout policy that throws an TimeoutRejectedException if no response is received from the OpenBreweryDb in 2 seconds.

I have also added a Polly retry policy to retry request that fail or timeout.

IAsyncPolicy<HttpResponseMessage> timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(2); 

The retry policy is set to retry up to three times.

IAsyncPolicy<HttpResponseMessage> retryPolicy = Policy
                .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
                .Or<Exception>()
                .RetryAsync(3)

I have a policy wrap with the latency policy at the center, the timeout around it and finally the retry around that.

IAsyncPolicy<HttpResponseMessage> latencyTimeoutAndRetryPolicy = Policy.WrapAsync(
    retryPolicy, timeoutPolicy, latencyPolicy);

What happens is –
In 50% of the requests to the OpenBreweryDb, the latency policy delays the request by 5 seconds.
If the latency is active, the timeout policy throws a TimeoutRejectedException.
Then retry policy retries the request again.

If you run the application you will see the timeout and retry policies logging to the console.

That’s it, the latency policy is very easy to use.

Full source code here.

Simmy Chaos Engine for .NET – Part 2, Resilience and Injected Faults

Full source code here.

I wrote a blog on using a Simmy Fault policy a few days ago, it is very simple to use by itself, but it is far more useful when used in combination with a resilience policy.

Take the scenario where I have added retry logic to my requests, but the requests never fail, how do I know the retry logic works the way I expect. This is where the fault policy shines.

I’m going to build on the previous post where I injected a fault 50 percent of the time when making http requests. In the previous post I had Simmy throw a HttpRequestException but this time I’m going to have Simmy return a HttpResponseMessage containing an InternalServerError.

Along with the fault policy, I am going add a simple retry policy, retrying up to three times.

Here’s how it will work –

The fault policy executes –

If the fault policy is active and a fault is to be returned (remember this happens 50% of the time) a InternalServerError is returned. The HttpClient does NOT make a request to the remote service

The retry policy executes. The handles clause sees the InternalServerError and the behavior clause of the retry kicks in and performs the retry

The fault policy executes again

The preceding two steps repeat until a request succeeds or the retry policy reaches is limit of 3 retries

 

If the fault policy is not active, or a fault is NOT to be returned

the HTTP client executes the request to the remote service

the handles clause of the retry determines whether a retry should be performed

 

This is what it looks like –

At the center is the HttpReqeust, around it is the fault policy and around everything is the retry policy.

To achieve all this in code is very simple, in ConfigureServices add the fault policy.

public void ConfigureServices(IServiceCollection services)
{
	HttpResponseMessage faultHttpResponseMessage = new HttpResponseMessage(HttpStatusCode.InternalServerError)
	{
		Content = new StringContent("Simmy swapped the Ok for an Internal Server Error")
	};
	AsyncInjectOutcomePolicy<HttpResponseMessage> faultPolicy = MonkeyPolicy.InjectFaultAsync(
		faultHttpResponseMessage,
		injectionRate: .5,
		enabled: () => true 
	);

When the fault policy executes, 50% of the time it will return an InternalServerError response, preempting the real request to the remote service.

Next is the retry policy, its behavior clause triggers if the HttpResponseMessage is not a success.

IAsyncPolicy<HttpResponseMessage> retryPolicy = Policy
	.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
	.RetryAsync(3, onRetry: (message, retryCount) =>
	{
		Console.WriteLine($"Retry: {retryCount}");
	});

Wrap the retry policy around the fault policy.

AsyncPolicyWrap<HttpResponseMessage> faultAndRetryWrap = Policy.WrapAsync(retryPolicy, faultPolicy);

Finally, create the HttpClientFactory, passing in the policy wrap. If you are not familiar with how the HttpClientFactory works read Steve Gordon’s series or my blog posts on it. If you want know how it works with Polly, take a look at my posts on that topic.

services.AddHttpClient("OpenBreweryDb", client =>
{
	client.BaseAddress = new Uri("https://api.openbrewerydb.org/breweries/");
	client.DefaultRequestHeaders.Add("Accept", "application/json");
}).AddPolicyHandler(faultAndRetryWrap);

To fire of the HttpClient request inside the BreweryController remains the same –

string requestEndpoint = $"?by_state={state}&by_name={name}";
var httpClient = _httpClientFactory.CreateClient("OpenBreweryDb");
var response = await httpClient.GetAsync(requestEndpoint);

Full source code here.

Simmy Chaos Engine for .NET – Part 1, Injecting Faults

Full source code here.

For quite a while I have been writing, presenting and making videos about using Polly to make applications more stable.

With this post I’m starting a series on how break your applications with a chaos engine, the kind you might have heard about from the likes of NetFlix.

The team behind Polly released a chaos engineering module in June 2019. It allows you to inject faults, latency and arbitrary behavior into your application.

There are two general ways of using these policies –
1. Within your own business logic (if you have access to it).
2. Within the calls to business logic (if you can’t or don’t want to change it).

I’m going to deal with the latter case in this post. I want to see how my code responds when failures occur in third party dependencies, since I have no control over those dependencies I have to introduce the errors myself.

Making a good service go bad
In the provided code I have dependency on remote service and I want make it seem that that service suffers from a high percentage of faults.
This example will make GET requests to an API that looks up breweries, from what I can tell it is a highly reliable API, but I will make look as though 50% of requests to it fail. The point of doing this is to see how my application reacts to these errors – does it do so gracefully, or does it fall on its face.

If you made requests to the API without interfering with them you should see a 100% success rate. But I want to see failures, so I’ll use the Fault Policy to inject exceptions.

First, I added two NuGet packages to my project – Polly.Contrib.Simmy and Microsoft.Extensions.Http.Polly to the project.

In Startup.cs I add the fault policy.

AsyncInjectOutcomePolicy<HttpResponseMessage> faultPolicy = MonkeyPolicy.InjectFaultAsync<HttpResponseMessage>(
	new HttpRequestException("Simmy threw an exception"), 
		injectionRate: .5,
		enabled: () => true
	);

The parameters specify the exception to throw, the percentage of requests that throw the exception, and whether the policy is enabled. You can use set the injection rate and whether the policy is enabled via configuration, but I’m not going to show that here.
In this case, I am throwing an HttpRequestException 50% of the time, and the policy is enabled.

Then create a HttpClientFactory for the OpenBreweryDb

services.AddHttpClient("OpenBreweryDb", client =>
{
	client.BaseAddress = new Uri("https://api.openbrewerydb.org/breweries/");
	client.DefaultRequestHeaders.Add("Accept", "application/json");
}).AddPolicyHandler(faultPolicy);

If you are not yet using the HttpClientFactory, the source code has an example for you too, check the BreweryNoHttpClientFactoryController.

Start up the application, it should open on port 5000 and make a request to look up Night Shift Brewing in Massachusetts. There is a 50% chance of an exception occurring with each request.

Try it out. You’ll see that my application does not handle these failures very well, it simply returns the error to original caller.

That’s it, you are now starting down the road of mixing in some chaos into your application.

What then?
Great, my application fails, but we always knew it could. There’s not much point introducing failures unless you plan to handle them in some way, and this is where you might add a retry policy to improve you likelihood of a successful request.

Of course, the Polly retry, or wait and retry policies would be ideal. I’ll show how to do just that in the next post.

Full source code here.