Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 69 additions & 1 deletion src/main/java/land/oras/Registry.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,21 @@ public final class Registry extends OCI<ContainerRef> {
*/
private @Nullable MeterRegistry meterRegistry;

/**
* Maximum number of attempts for retryable requests (1 = no retry)
*/
private int maxRetries = 3;

/**
* Initial delay between retries in milliseconds
*/
private long retryDelayMs = 500L;

/**
* Upper bound on retry delay in milliseconds
*/
private long maxRetryDelayMs = 30_000L;

/**
* Constructor
*/
Expand Down Expand Up @@ -290,12 +305,28 @@ private void setMeterRegistry(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}

private void setMaxRetries(int maxRetries) {
this.maxRetries = maxRetries;
}

private void setRetryDelayMs(long retryDelayMs) {
this.retryDelayMs = retryDelayMs;
}

private void setMaxRetryDelayMs(long maxRetryDelayMs) {
this.maxRetryDelayMs = maxRetryDelayMs;
}

/**
* Build the provider
* @return The provider
*/
private Registry build() {
HttpClient.Builder clientBuilder = HttpClient.Builder.builder().withSkipTlsVerify(skipTlsVerify);
HttpClient.Builder clientBuilder = HttpClient.Builder.builder()
.withSkipTlsVerify(skipTlsVerify)
.withMaxRetries(maxRetries)
.withRetryDelay(retryDelayMs)
.withMaxRetryDelay(maxRetryDelayMs);
if (caFilePath != null) {
clientBuilder = clientBuilder.withCaFile(caFilePath);
}
Expand Down Expand Up @@ -1565,6 +1596,9 @@ public Builder from(Registry registry) {
this.registry.setSkipTlsVerify(registry.skipTlsVerify);
this.registry.setExecutorService(registry.executorService);
this.registry.setParallelism(registry.maxConcurrentDownloads);
this.registry.setMaxRetries(registry.maxRetries);
this.registry.setRetryDelayMs(registry.retryDelayMs);
this.registry.setMaxRetryDelayMs(registry.maxRetryDelayMs);
if (registry.meterRegistry != null) {
this.registry.setMeterRegistry(registry.meterRegistry);
}
Expand Down Expand Up @@ -1743,6 +1777,40 @@ public Builder withMeterRegistry(MeterRegistry meterRegistry) {
return this;
}

/**
* Set the maximum number of attempts for retryable requests (default: 3).
* A value of 1 disables retries entirely.
* Retryable conditions: HTTP 429, HTTP 5xx, network errors (IOException / timeout).
* Token-refresh requests are never retried regardless of this setting.
* @param maxRetries Maximum attempts (must be &gt;= 1)
* @return The builder
*/
public Builder withMaxRetries(int maxRetries) {
registry.setMaxRetries(maxRetries);
return this;
}

/**
* Set the initial delay before the first retry in milliseconds (default: 500).
* Subsequent delays are doubled up to the limit set by {@link #withMaxRetryDelay}.
* @param retryDelayMs Initial delay in milliseconds (must be &gt;= 0)
* @return The builder
*/
public Builder withRetryDelay(long retryDelayMs) {
registry.setRetryDelayMs(retryDelayMs);
return this;
}

/**
* Set the upper bound on retry delay in milliseconds (default: 30 000).
* @param maxRetryDelayMs Maximum delay cap in milliseconds (must be &gt;= 0)
* @return The builder
*/
public Builder withMaxRetryDelay(long maxRetryDelayMs) {
registry.setMaxRetryDelayMs(maxRetryDelayMs);
return this;
}

/**
* Return a new builder
* @return The builder
Expand Down
Loading
Loading