Skip to content

Comments

Feature/optimization http client instance#57

Merged
TomPallister merged 11 commits intoThreeMammals:developfrom
geffzhang:feature/Optimization-HttpClient-instance
Mar 8, 2017
Merged

Feature/optimization http client instance#57
TomPallister merged 11 commits intoThreeMammals:developfrom
geffzhang:feature/Optimization-HttpClient-instance

Conversation

@geffzhang
Copy link
Contributor

Instantiating an HttpClient for every request can possible exhaust the number of sockets available under heavy loads. Microsoft patterns & practices https://github.com/mspnp/performance-optimization/blob/master/ImproperInstantiation/docs/ImproperInstantiation.md goes into detail on this issue, How to Cache HttpClient Instances? I now use MemoryCache, How to do best

@TomPallister
Copy link
Member

@geffzhang ignore my previous comment.

Unfortunately you cannot set HttpClientHandler after HttpClient has been instantiated.

Copy link
Member

@TomPallister TomPallister left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have left some comments. Please review.

I have also noticed we do not need cookie container as cookies are just set as headers...I did not realise this. If we did use the cookie container im not sure implementation of caching HttpClient would be thread safe. However cookies are stored on HttpRequestMessage which is instantiated per request and is thread safe.

_memoryCache = memoryCache;
}

public void Set(string id, IHttpClient counter, TimeSpan expirationTime)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string id maybe call this key, IHttpClient counter maybe call this httpClient


namespace Ocelot.Requester
{
public interface IHttpClientMessageCacheHandler
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe call this IHttpClientCache


namespace Ocelot.Requester
{
public class MemoryHttpClientMessageCacheHandler : IHttpClientMessageCacheHandler
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call this MemoryCacheHttpClientCache

{
public class HttpClientHttpRequester : IHttpRequester
{
private IHttpClientMessageCacheHandler _cacheHandlers;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make this readonly

baseUrl = $"{baseUrl}{request.QosProvider.CircuitBreaker.CircuitBreakerPolicy.PolicyKey}";
}

IHttpClient httpClient = _cacheHandlers.Get(baseUrl);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IHttpClient to be var (we use var everywhere else)

internal class HttpClientBuilder : IHttpClientBuilder
{
private readonly Dictionary<int, Func<DelegatingHandler>> _handlers = new Dictionary<int, Func<DelegatingHandler>>();
private TimeSpan? _timeout;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never set so we can delete


var client = new HttpClient(CreateHttpMessageHandler(httpclientHandler));

if (_timeout.HasValue)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never set so we dont need this code

client.Timeout = _timeout.Value;
}

if (_defaultHeaders == null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never set so we dont need this code

return new HttpClientWrapper(client);
}

foreach (var header in _defaultHeaders)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never set so we dont need this code

using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer })
builder.WithCookieContainer(request.CookieContainer);

string baseUrl = $"{request.HttpRequestMessage.RequestUri.Scheme}://{request.HttpRequestMessage.RequestUri.Authority}";
Copy link
Member

@TomPallister TomPallister Mar 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make a private method to do this..will look nicer.

Copy link
Contributor Author

@geffzhang geffzhang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I has modified according to your views

return this;
}

public IHttpClientBuilder WithDefaultRequestHeaders(Dictionary<string, string> headers)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

@TomPallister TomPallister merged commit 9bb8612 into ThreeMammals:develop Mar 8, 2017
@geffzhang geffzhang deleted the feature/Optimization-HttpClient-instance branch March 9, 2017 04:08
geffzhang added a commit that referenced this pull request Mar 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants