gaborgsomogyi commented on code in PR #29499:
URL: https://github.com/apache/flink/pull/29499#discussion_r4443811549


##########
flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/NativeS3FileSystemFactory.java:
##########
@@ -312,6 +312,31 @@ public class NativeS3FileSystemFactory implements 
FileSystemFactory, MetricsAwar
                                     + "configured backoff and retry count are 
exhausted. Disabled by default "
                                     + "so the retry/backoff settings above 
fully govern retry behavior.");
 
+    /** How the AWS SDK clients retry failed requests, see {@link 
#RETRY_MODE}. */
+    public enum RetryMode {
+        STANDARD,
+        ADAPTIVE
+    }
+
+    public static final ConfigOption<RetryMode> RETRY_MODE =
+            ConfigOptions.key("s3.retry.mode")
+                    .enumType(RetryMode.class)
+                    .defaultValue(RetryMode.STANDARD)
+                    .withDescription(
+                            "How the AWS SDK retries failed requests. 
'standard' (default): every "

Review Comment:
   Changed.



##########
flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/NativeS3FileSystemFactory.java:
##########
@@ -312,6 +312,31 @@ public class NativeS3FileSystemFactory implements 
FileSystemFactory, MetricsAwar
                                     + "configured backoff and retry count are 
exhausted. Disabled by default "
                                     + "so the retry/backoff settings above 
fully govern retry behavior.");
 
+    /** How the AWS SDK clients retry failed requests, see {@link 
#RETRY_MODE}. */
+    public enum RetryMode {
+        STANDARD,
+        ADAPTIVE
+    }

Review Comment:
   Kept. Flink nests the enum of an option in the class that declares it (e.g. 
`JobManagerOptions.SchedulerType`), and this factory holds all the options of 
the module.



##########
flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/S3RetryStrategyFactory.java:
##########
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.fs.s3native;
+
+import org.apache.flink.annotation.Internal;
+
+import software.amazon.awssdk.retries.AdaptiveRetryStrategy;
+import software.amazon.awssdk.retries.StandardRetryStrategy;
+import software.amazon.awssdk.retries.api.BackoffStrategy;
+import software.amazon.awssdk.retries.api.RetryStrategy;
+import software.amazon.awssdk.retries.internal.DefaultAdaptiveRetryStrategy;
+
+import java.time.Duration;
+import java.util.Arrays;
+
+/**
+ * Builds the AWS SDK {@link RetryStrategy} used by the native S3 client's 
sync/async clients: the
+ * standard or the adaptive one, see {@link 
NativeS3FileSystemFactory#RETRY_MODE}. The delays are
+ * validated by {@link S3ClientProvider.Builder}.
+ */
+@Internal
+final class S3RetryStrategyFactory {
+
+    private S3RetryStrategyFactory() {}
+
+    static RetryStrategy create(
+            NativeS3FileSystemFactory.RetryMode retryMode,
+            int maxRetries,
+            Duration retryBaseDelay,
+            Duration retryThrottleBaseDelay,
+            Duration retryMaxBackoff,
+            boolean retryCircuitBreakerEnabled) {
+        BackoffStrategy backoff = 
BackoffStrategy.exponentialDelay(retryBaseDelay, retryMaxBackoff);
+        BackoffStrategy throttlingBackoff =
+                BackoffStrategy.exponentialDelay(retryThrottleBaseDelay, 
retryMaxBackoff);
+
+        switch (retryMode) {
+            case STANDARD:
+                return StandardRetryStrategy.builder()
+                        .maxAttempts(maxRetries + 1)
+                        .backoffStrategy(backoff)
+                        .throttlingBackoffStrategy(throttlingBackoff)
+                        .circuitBreakerEnabled(retryCircuitBreakerEnabled)
+                        .build();
+            case ADAPTIVE:
+                return createAdaptive(
+                        maxRetries, backoff, throttlingBackoff, 
retryCircuitBreakerEnabled);
+            default:
+                throw new IllegalArgumentException(
+                        "Unknown retry mode: "
+                                + retryMode
+                                + ". Supported values: "
+                                + 
Arrays.toString(NativeS3FileSystemFactory.RetryMode.values()));
+        }
+    }
+
+    private static RetryStrategy createAdaptive(
+            int maxRetries,
+            BackoffStrategy backoff,
+            BackoffStrategy throttlingBackoff,
+            boolean retryCircuitBreakerEnabled) {
+        AdaptiveRetryStrategy.Builder builder =
+                AdaptiveRetryStrategy.builder()
+                        .maxAttempts(maxRetries + 1)
+                        .backoffStrategy(backoff)
+                        .throttlingBackoffStrategy(throttlingBackoff);
+        // The public builder of the adaptive strategy has no switch for the 
circuit breaker, so it
+        // would stay on and a throttling storm would drain its token bucket 
within seconds (see
+        // RETRY_CIRCUIT_BREAKER_ENABLED). The SDK's own builder has the 
switch.
+        ((DefaultAdaptiveRetryStrategy.Builder) builder)
+                .circuitBreakerEnabled(retryCircuitBreakerEnabled);
+        return builder.build();

Review Comment:
   No. `createAdaptive` is only called for `ADAPTIVE`, `STANDARD` uses the 
public `StandardRetryStrategy` builder.



##########
flink-filesystems/flink-s3-fs-native/src/test/java/org/apache/flink/fs/s3native/NativeS3FileSystemFactoryTest.java:
##########
@@ -439,6 +439,29 @@ void testRetryCircuitBreakerEnabledExplicitlyConfigured() 
throws Exception {
         
assertThat(createFs(config).getClientProvider().isRetryCircuitBreakerEnabled()).isTrue();
     }
 
+    @Test
+    void testRetryModeDefault() throws Exception {
+        assertThat(createFs(baseConfig()).getClientProvider().getRetryMode())
+                .isEqualTo(NativeS3FileSystemFactory.RetryMode.STANDARD);
+    }
+
+    @Test
+    void testRetryModeExplicitlyConfigured() throws Exception {

Review Comment:
   Covered by `S3RetryStrategyFactoryTest`, which asserts the strategy type per 
mode. Added tests in `S3ClientProviderTest` that the built client uses the 
strategy of the mode, so this test only needs to check that the option is read.



##########
flink-filesystems/flink-s3-fs-native/src/test/java/org/apache/flink/fs/s3native/NativeS3FileSystemFactoryTest.java:
##########
@@ -439,6 +439,29 @@ void testRetryCircuitBreakerEnabledExplicitlyConfigured() 
throws Exception {
         
assertThat(createFs(config).getClientProvider().isRetryCircuitBreakerEnabled()).isTrue();
     }
 
+    @Test
+    void testRetryModeDefault() throws Exception {
+        assertThat(createFs(baseConfig()).getClientProvider().getRetryMode())
+                .isEqualTo(NativeS3FileSystemFactory.RetryMode.STANDARD);
+    }
+
+    @Test
+    void testRetryModeExplicitlyConfigured() throws Exception {
+        Configuration config = baseConfig();
+        config.set(
+                NativeS3FileSystemFactory.RETRY_MODE, 
NativeS3FileSystemFactory.RetryMode.ADAPTIVE);
+        assertThat(createFs(config).getClientProvider().getRetryMode())
+                .isEqualTo(NativeS3FileSystemFactory.RetryMode.ADAPTIVE);
+    }
+
+    @Test
+    void testRetryModeIsReadFromTheLowerCaseValueOfAFlinkConfigFile() throws 
Exception {

Review Comment:
   Same as above.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to