Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[csharp][netcore-httpclient] Reuse HttpClient, Allow use of external HttpClient, Fix Socket Exhaustion, Alternative With Constructor Injection #9085
[csharp][netcore-httpclient] Reuse HttpClient, Allow use of external HttpClient, Fix Socket Exhaustion, Alternative With Constructor Injection #9085
Changes from 8 commits
33bcb4a
68b5d76
dcf3e2d
5ec0b1d
2a1227e
402c875
f7b07fa
ef8f51c
e18dd4b
c3aed2e
d08d2b9
ddcaad8
e1ca890
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the code sample in the readme:
Looks like if the HttpClient is provided, one can obtain its HttpClientHandler, right?
If that's the case, I would suggest simply ask for HttpClient in the constructor to make it easier for the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is unfortunately not the case. You can not acquire the handler from the HttpClient once it is constructed. The handler is used for setting/retrieving cookies as well as configuring the proxy and client certificates. We could say that in case a user passed in their own HttpClient that they would be handling all of that themselves or simply have to live with the fact that it doesn't work. Hence why I was wondering whether we should at least give some kind of warning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just saw this: https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-5.0#httpclient-and-net-core
Shall we simply use
HttpClient = new HttpClient();
as it should pick the best available transport based on the platform? In other words, ApiClient will not store the HttpClientHandler.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, we are no longer able to set proxy options and client certificates anymore if we do that. Instantiating HttpClientHandler creates an underlying actual handler which is SocketsHttpHandler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be clear, what we are doing by default is exactly what HttpClient and its default constructor are doing:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also thinked about the validation of both parameters as you.
But actually i think that I won't to get a complex DI for these few not so useful parameters.
I test it in a real net core application.
I see more things:
What do you think will be the usage, the client is prepared that way for example:
Now i need to register the Api passing some related options like the basePath or configuration and the client or the api client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you need customize the DI injection by running a lambda function that then sets the correct configuration at that point.
Right now adding just the HttpClient is not a supported UseCase. If you say this is relevant for you as well, and you want to use the client from IHttpClientFactory then we'll figure out a way to do that.
I talked about this also with @wing328 and we actually wanted to add a way to do this later if people request it. It appears you may have a usecase already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a new version that includes a switch to disable the exception and the features that don't work if handler isn't present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why in those 3+ years of net core, no one had this issue using a swagger codegen.
Maybe because in the official startup documentation they promote NSwag, effectively the only one actually support the injection of an HttpClient. They also underline very well the issues\tradeoffs in the HttpClient and how they manage it with the factory in the DI.
We moved to net core with a few projects in this years, those services consume others using rest api, with a Swagger codgen. In this days I monitored a strange pressure on the production environment, and I found the socket exsaustion, done by ourself with a chatty client. I compared the different behavior of the vanilla codegen in both framework, monitoring with wireshark:
The breaking change is inside RestSharp, it has an issue open but the project seems aware to this difficult change to support net core and I think it has no future plans to fix it. The real change is inside the HttpWebRequest that actually in Net Core no more has a static lifecycle and create a new HttpClient.
So RestSharp is not a valid production library for net core, at all.
This means also Swagger is not a valid choice for net core.
Swagger seems no more active, the main author, William, is here now on OpenApi, reviewing you now (William thank you for the projects, they are great).
So the choice for us are:
Your fix is just enough to avoid the exsaustion now.
But having a client that not fit easily in the DI can move us to choose another more solid way for the future.
But I also see a lot of interest in this PR and on this project to move to a working client for net core so I will await and cooperate with you if I can give some support.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've different suggestions but let's go with what you've so far. We can resume the discussion after the merge.