2
votes

I'm using RestSharp to communicate with a .Net Core Web API. Both Client and Server are written by me.

I have a suite of Services all inheriting a Base class which contains an async method to perform the request via a RestClient. Here is the method within the base class that creates the RestClient.

    private async Task<ServiceResponse> RequestAsync(ServiceRequest request)
    {
        try
        {
            var result = await new RestClient(_digiCore.Config.GetApiBaseUrl()).ExecuteTaskAsync(request.Request, request.CancellationTokenSource.Token);

            switch (result.StatusCode)
            {
                case HttpStatusCode.OK:
                case HttpStatusCode.Created:
                case HttpStatusCode.NoContent:
                    return new ServiceResponse
                    {
                        Code = ServiceResponseCode.Success,
                        Content = result.Content
                    };
                // User wasn't authenticated for this one - better luck next time!
                case HttpStatusCode.Unauthorized:
                    Logger.LogError($"Unauthorized {request.Method.ToString()}/{request.Path}");
                default:
                    Logger.LogError($"An error occurred {request.Method.ToString()}/{request.Path}");
            }
        }
        catch (Exception e)
        {
            Logger.LogError($"A Rest Client error occurred {request.Method.ToString()}/{request.Path}");
        }
    }

My understanding is that the RestClient (unlike HttpClient) is thread safe and OK to create a new instance each time.

When Load testing my application, one I reach a certain point, I find that I occasionally receive the following response back from the API. Refreshing the page might bring back the correct result, or I might get another error. When the Load Test has finished everything goes back to normal. The numbers of the load test are nothing crazy, so its started to get me worried about real-life performance...

Only one usage of each socket address (protocol/network address/port) is normally permitted

I believe this is down to port exhaustion. Both API and Client are running in Azure as App services.

I have tried making the RestClient part of a singleton service, and checked that it is only created once - but this did not alleviate the issue.

I have also looked into setting the DefaultConnectionLimit in the Startup function of my startup class from the default (2) to 12, but I did not see any improvements here either.

I'm really struggling to see how I can improve this... Any help would be greatly appreciated

1

1 Answers

4
votes

Found out the reason for this...

It seems there is currently an issue with RestSharp whereby socket connections are not closed down immediately and instead are left in TIME_WAIT state.

This issue is currently logged with the RestSharp guys here ->

https://github.com/restsharp/RestSharp/issues/1322

I have chosen to switch over to using HttpClient - and running the exact same load test I had zero problems.

Here is an screenshot taken from Azure showing the difference between the two load tests.

  1. Was with my app using RestSharp
  2. Was with my app using Http Client

Hope this helps somebody. It's a shame I had to ditch RestSharp as it was a nice little library - unfortunately with an issue like this it's just too risky to run in a Production environment.

enter image description here