Thursday 22 November 2018

HttpClient reuse and throughput

If you are creating HttpClient everytime you make an outbound http call from your application then with all due respect you are doing it wrong. There are multiple resources available across the internet that explain the fact that HttpClient instances should be reused throughout the lifetime of the application as it provides better throughput.

If you create an instance of httpclient for each outbound http call, as the number of parallel outbound increases, you will start to see issues like port exhaustion or connection error etc.

Sources: Link # 1 Link # 2

Best Practices?

1. Even though HttpClient should be reused, it is to be kept in mind that the responsibility is on you to ensure that your code does not cause trouble. For example - 
      a. You should maintain different HttpClients for each base URL. If you try to manipulate base urls for parallel calls, you are asking for trouble.
      b. Any Http headers that you intend to send as part of Http request, should be included and sent as part of HttpRequestMessage. We should avoid setting headers in HttpClient.DefaultHeaders and manipulating them for each call. Headers in HttpClient are .NET dictionary (not ConcurrentDictionary) and therefore it is not thread-safe :).

2. It is better to use any of the DI containers to create and maintain Singleton instance of HttpClient or a custom Factory.

3. Any other ServiceApiClients that use Http as underlying protocol should either ensure that HttpClient is resued or you need to ensure that you its implementation is such that you can reuse a single instance of that across calls. In fact, there are many out of the box Azure SDK Clients recommend that instances should be resued e.g. DocumentDbClient, ServiceBusClient, Azure Storage Client etc.

Thursday 8 November 2018

.NET Core Web App as Windows Service : Handling slow startup

.NET core is fast becoming the first choice of development framework as it brings the benefit of cross-platform compatibility. Of course, it is fast too.

If you make a .NET core web application, you would notice that the IWebHost presents us with 2 ways to host the web application 

1. Run
2. RunAsService

RunAsService is quite useful if you want to host your .NET core web application as a windows service instead of a standalone executable. RunAsService does not give us with much flexibility though. 

Enhancement

If you want to handle what happens before ASP.NET core starts or after it has started, you are better suited to inherit from "WebHostService" class and use that to host the asp.net web application.

It is described here.

With this, you will be able to hook your custom code in following places.

1. OnStarting
2. OnStarted
3. OnStopping
4. OnStopped

Enhancement 2

If your start up code is a bit slow, then you have further challenges. In classic windows service projects, you get an option to request additional start up time though code. However, you can not do that in .NET core's web host as those hook points are not available.

So what do you do?

Couple of options:

1. Move your slow start up logic to background thread using Tasks.
2. Use parallel tasks.
3. Use timer to call back into the logic to perform start up work after some time :).