Skip to content

Add retry support for HTTP execution failure#1702

Open
balamurugana wants to merge 2 commits into
minio:masterfrom
balamurugana:Add-retry-support-for-HTTP-execution-failure
Open

Add retry support for HTTP execution failure#1702
balamurugana wants to merge 2 commits into
minio:masterfrom
balamurugana:Add-retry-support-for-HTTP-execution-failure

Conversation

@balamurugana
Copy link
Copy Markdown
Member

No description provided.

@balamurugana balamurugana marked this pull request as draft May 11, 2026 15:13
@balamurugana balamurugana force-pushed the Add-retry-support-for-HTTP-execution-failure branch 8 times, most recently from 5475995 to 81ad96c Compare May 12, 2026 08:11
@balamurugana balamurugana force-pushed the Add-retry-support-for-HTTP-execution-failure branch from 81ad96c to 9e8f51f Compare May 12, 2026 08:25
@balamurugana balamurugana marked this pull request as ready for review May 12, 2026 08:25
Comment on lines +95 to +102
408, // Request Timeout
429, // Too Many Requests
499, // Client Closed Request (nginx)
500, // Internal Server Error
502, // Bad Gateway
503, // Service Unavailable
504, // Gateway Timeout
520); // Cloudflare unknown error
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

should we use http.StatusTooManyRequests kind values instead of hardcoded ones like 429?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

okhttp does not have those enums? java.net.HttpURLConnection has limited constants. I think we can avoid mixed usage.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ok

Copy link
Copy Markdown

@shtripat shtripat left a comment

Choose a reason for hiding this comment

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

lgtm

Copy link
Copy Markdown
Contributor

@allanrogerr allanrogerr left a comment

Choose a reason for hiding this comment

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

The new retry logic including interceptor, setRetry replacement logic, body-replay across retries, NPE-safe trace formatting are not unit-tested. The functional tests cover a happy path, but

  • no test creates a scenario to verify retry actually fires,
  • no test verifies the maxRetries boundary,
  • no test checks setRetry replaces the interceptor correctly,
  • no test exercises a malformed request.method()
    Could you have Claude generate some tests please?

Comment on lines +644 to +645
.replaceAll("Signature=([0-9a-f]+)", "Signature=*REDACTED*")
.replaceAll("Credential=([^/]+)", "Credential=*REDACTED*"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These could be stored as static final Pattern to avoid recompilation every trace event

Comment on lines +152 to +154
int i = 0;
boolean found = false;
for (i = 0; i < interceptors.size(); i++) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any reason for re-reinitialising?

if (traceStream == null) return this.httpClient;

OkHttpClient httpClient = this.httpClient;
List<Interceptor> interceptors = httpClient.interceptors();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This look very close to the code on line 151. Any reason for the duplication? This could be refactored out as a method.

* Sets request retry parameters. Any null/invalid values disable retry.
*
* <pre>Example:{@code
* minioClient.setRetryParameters(ImmutableSet.of(408, 504), 250, 3);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
* minioClient.setRetryParameters(ImmutableSet.of(408, 504), 250, 3);
* minioClient.setRetry(ImmutableSet.of(408, 504), 250, 3);

Copy link
Copy Markdown
Contributor

@allanrogerr allanrogerr left a comment

Choose a reason for hiding this comment

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

Additional comments @balamurugana PTAL

Comment on lines +353 to +358
boolean statusRetryInterceptorFound = true;

OkHttpClient httpClient = this.httpClient;
// FIXME: enable retry for all request.
// if (!s3request.retryFailure()) {
// httpClient = httpClient.newBuilder().retryOnConnectionFailure(false).build();
// }
StringBuilder traceBuilder = new StringBuilder(request.httpTraces());
if (!statusRetryInterceptorFound && traceStream != null) {
traceStream.print(request.httpTraces());
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not static final if it is never reassigned? Also all branches using this boolean are unreachable. Perhaps there is an unfinished idea here?

builder.addInterceptor(interceptor);
}

this.httpClient = builder.build();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems to have the makings of a race:

  1. read: List interceptors = this.httpClient.interceptors();
  2. read: OkHttpClient.Builder builder = this.httpClient.newBuilder();
  3. write: this.httpClient = builder.build();

Two concurrent setRetry calls can read and assign protected volatile OkHttpClient httpClient. This may not be ideal.

try {
return Method.valueOf(value.toUpperCase(Locale.US).trim());
} catch (IllegalArgumentException e) {
return null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Invocations of the method may hit NPE - e.g. traceBuilder.append(method.toString())

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.

3 participants