Skip to content
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

[bug]: TCP ports exhaution or stale DNS resolution #3681

Closed
1 task
fredericDelaporte opened this issue Sep 9, 2024 · 3 comments
Closed
1 task

[bug]: TCP ports exhaution or stale DNS resolution #3681

fredericDelaporte opened this issue Sep 9, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@fredericDelaporte
Copy link

fredericDelaporte commented Sep 9, 2024

Description

The default SearchClient implementation for the .Net client does not follow the HttpClient guidelines and exposes the user to either exhausting the TCP port of the computer or have stale DNS resolution in case of a changes in the Algolia DNS.

  • An application using the SearchClient by instantiating it for each query will risk causing TCP port exhaustion on the computer on which it runs.
  • An application using it as a singleton will miss any DNS update that may occur on Algolia side.

(And there is no guidance on the "Get started" page about the intended lifecycle for the client.)

We can implement our own Algolia IHttpRequester as a work around, but it would be better for the default implementation to be reliable "out of the box", at least with some usage guidelines.

Language

CSharp

Client

Search

Steps to reproduce

Check the code:
https://github.com/algolia/api-clients-automation/blob/265d3923b79c2329e965dc6bcd34b5134ddcd7cf/clients/algoliasearch-client-csharp/algoliasearch/Http/AlgoliaHttpRequester.cs#L21C1-L25C8

  private readonly HttpClient _httpClient = new(
    new TimeoutHandler
    {
      InnerHandler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip }
    });

So, that is a HttpClient creation, ultimately, for each instance of SearchClient, using neither a SocketsHttpHandler with a configured PooledConnectionLifetime nor an IHttpClientFactory. The former is required for using the SearchClient as a singleton while avoiding stale DNS resolution. The later is required for using the SearchClient by instantiating it for each usage while avoiding TCP port exhaustion.

Relevant log output

No response

Self-service

  • I'd be willing to fix this bug myself.
@fredericDelaporte fredericDelaporte added the bug Something isn't working label Sep 9, 2024
@fredericDelaporte
Copy link
Author

fredericDelaporte commented Sep 9, 2024

I may be wrong but it looks to me the SearchClient is intended to be used as a singleton.

In such case, the trouble could be fixed for .net Core 2.1 and higher by using the SocketsHttpHandler. But that would require targeting .net core 2.1 or higher (it is not in netstandard 2.1) and having some compilation conditional code for supporting other targets like the old .Net Framework.

It would keep the possible stale DNS trouble for non .net core targets. Users would have to work around this by restarting their application or, to better handle it, switch to a "singleton" with a limited lifetime, regularly renewed with a new instance.

Otherwise, if the SearchClient should be instantiated at each usage, then it would have first to become disposable for properly disposing the HttpRequest it creates. Then it should be changed to use a HttpClientFactory and avoid the TCP port exhaustion risk.

@morganleroi
Copy link
Contributor

Hello @fredericDelaporte ,

You're right, we expect the instantiated client to be reused. And you're right about the missing documentation. I'll reuse part of the V6 documentation that is still relevant for the client setup.

To keep performance optimal, you should reuse the client instance for every request. To do this, inject the SearchClient as singleton in the service provider.

Please not that the client behaviour regarding DNS freshness is untouched.

@morganleroi
Copy link
Contributor

@fredericDelaporte

I just updated the V7 documentation with a dedicated section about the client instantiation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants