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

Move HTTP client creation inside the API client retry callback block. #8558

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

isoos
Copy link
Collaborator

@isoos isoos commented Feb 11, 2025

No description provided.

@isoos isoos requested a review from jonasfj February 11, 2025 12:44
Copy link
Member

@jonasfj jonasfj 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 no objections, but I also don't see what possible good this could do.

(A) I'm assuming this is only used in testing.
(B) An http.Client should not need to be recreated between retries, it's a connection pool, if there is a broken connection it'll be closed.

So I don't really understand what this would do (what am I missing?)

@isoos
Copy link
Collaborator Author

isoos commented Feb 12, 2025

I'm going to introduce a withRetryHttpClient wrapper, that would be used in the non-testing code too, following the same principles as here: may create a client inside of it, retries on various exception (not like the current RetryClient). I thought that a natural first step would be to make this method into the shape of the new wrapper so the transition step is easier to follow.

@isoos
Copy link
Collaborator Author

isoos commented Feb 12, 2025

An http.Client should not need to be recreated between retries, it's a connection pool, if there is a broken connection it'll be closed.

Though, this is a bug here: we create a Client, we try to use inside a retry block, and on any exception, we close it. However, the next retry round is now going to be run on a closed client.

@isoos
Copy link
Collaborator Author

isoos commented Feb 13, 2025

Hm, the planned refactor of the withRetryHttpClient method is tought. This is a crude version of it:

Future<R> _withRetryHttpClient<R>(
  /// The callback function that may be retried on transient errors.
  Future<R> Function(http.Client client) fn, {
  FutureOr<http.Client> Function()? clientFn,
  http.Client? client,
}) async {
  return await retry(
    () async {
      final skipClosing = client != null;
      http.Client? httpClient;
      try {
        httpClient = client ?? await clientFn!();
        return await fn(httpClient);
      } finally {
        if (!skipClosing) {
          httpClient?.close();
        }
      }
    },
    maxAttempts: 3,
    retryIf: _retryIf,
  );
}

However, if we use client, then it is not recreated on retries, which may be needed to skip a stale connection, and if we use clientFn, then it is recreated all the time, which may be okay for one-off tasks, but is not that beneficial for e.g. search client connections. wdyt? Should we rather have a state tracking wrapper inside a custom class or a subclass of http.Client?

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