1 /*
2 * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15 package com.amazonaws.retry;
16
17 import com.amazonaws.AmazonClientException;
18 import com.amazonaws.AmazonServiceException;
19 import com.amazonaws.AmazonWebServiceRequest;
20 import com.amazonaws.ClientConfiguration;
21 import java.io.IOException;
22
23 /**
24 * This class includes a set of pre-defined retry policies, including default
25 * policies used by SDK.
26 */
27 public class PredefinedRetryPolicies {
28
29 /** No retry policy **/
30 public static final RetryPolicy NO_RETRY_POLICY = new RetryPolicy(
31 RetryPolicy.RetryCondition.NO_RETRY_CONDITION,
32 RetryPolicy.BackoffStrategy.NO_DELAY,
33 0, // maxErrorRetry
34 false); // honorMaxErrorRetryInClientConfig
35
36 /* SDK default */
37
38 /** SDK default max retry count for legacy retry mode **/
39 public static final int DEFAULT_MAX_ERROR_RETRY = 3;
40
41 /** SDK default max retry count for standard retry mode **/
42 public static final int DEFAULT_MAX_ERROR_RETRY_STANDARD_MODE = 2;
43
44 /**
45 * SDK default retry policy. Amazon DynamoDB has a custom retry policy that is used when no
46 * {@link ClientConfiguration} is provided.
47 */
48 public static final RetryPolicy DEFAULT;
49
50 /* Default for DynamoDB client */
51
52 /** Default max retry count for DynamoDB client **/
53 public static final int DYNAMODB_DEFAULT_MAX_ERROR_RETRY = 10;
54
55 /** Default policy for DynamoDB client **/
56 public static final RetryPolicy DYNAMODB_DEFAULT;
57
58 /* Reusable retry policy components */
59
60 /**
61 * The SDK default retry condition, which checks for various conditions in
62 * the following order:
63 * <ul>
64 * <li>Never retry on requests with non-repeatable content;
65 * <li>Retry on client exceptions caused by IOException;
66 * <li>Retry on service exceptions that are either 500 internal server
67 * errors, 503 service unavailable errors, service throttling errors or
68 * clock skew errors.
69 * </ul>
70 */
71 public static final RetryPolicy.RetryCondition DEFAULT_RETRY_CONDITION = new SDKDefaultRetryCondition();
72
73 /**
74 * The SDK default back-off strategy, which increases exponentially up to a max amount of delay. It also applies a larger
75 * scale factor upon service throttling exception.
76 */
77 public static final RetryPolicy.BackoffStrategy DEFAULT_BACKOFF_STRATEGY =
78 new PredefinedBackoffStrategies.SDKDefaultBackoffStrategy();
79
80 /**
81 * The SDK default back-off strategy, which increases exponentially up to a max amount of delay. It also applies a larger
82 * scale factor upon service throttling exception.
83 */
84 public static final V2CompatibleBackoffStrategy DEFAULT_BACKOFF_STRATEGY_V2 =
85 new PredefinedBackoffStrategies.SDKDefaultBackoffStrategy();
86
87 /**
88 * The default back-off strategy for DynamoDB client, which increases
89 * exponentially up to a max amount of delay. Compared to the SDK default
90 * back-off strategy, it applies a smaller scale factor.
91 */
92 public static final RetryPolicy.BackoffStrategy DYNAMODB_DEFAULT_BACKOFF_STRATEGY =
93 new PredefinedBackoffStrategies.SDKDefaultBackoffStrategy(PredefinedBackoffStrategies.DYNAMODB_DEFAULT_BASE_DELAY,
94 PredefinedBackoffStrategies.SDK_DEFAULT_THROTTLED_BASE_DELAY,
95 PredefinedBackoffStrategies.SDK_DEFAULT_MAX_BACKOFF_IN_MILLISECONDS);
96
97 static {
98 DEFAULT = getDefaultRetryPolicy();
99 DYNAMODB_DEFAULT = getDynamoDBDefaultRetryPolicy();
100 }
101
102 /**
103 * Returns the SDK default retry policy. This policy will honor the
104 * maxErrorRetry set in ClientConfiguration.
105 *
106 * @see ClientConfiguration#setMaxErrorRetry(int)
107 */
108 public static RetryPolicy getDefaultRetryPolicy() {
109 return new RetryPolicy(DEFAULT_RETRY_CONDITION,
110 DEFAULT_BACKOFF_STRATEGY,
111 DEFAULT_MAX_ERROR_RETRY,
112 true,
113 true);
114 }
115
116 /**
117 * Returns the default retry policy for DynamoDB client. This policy will
118 * honor the maxErrorRetry set in ClientConfiguration.
119 *
120 * @see ClientConfiguration#setMaxErrorRetry(int)
121 */
122 public static RetryPolicy getDynamoDBDefaultRetryPolicy() {
123 return new RetryPolicy(DEFAULT_RETRY_CONDITION,
124 DYNAMODB_DEFAULT_BACKOFF_STRATEGY,
125 DYNAMODB_DEFAULT_MAX_ERROR_RETRY,
126 true,
127 true);
128 }
129
130 /**
131 * Returns the SDK default retry policy with the specified max retry count.
132 */
133 public static RetryPolicy getDefaultRetryPolicyWithCustomMaxRetries(int maxErrorRetry) {
134 return new RetryPolicy(DEFAULT_RETRY_CONDITION,
135 DEFAULT_BACKOFF_STRATEGY,
136 maxErrorRetry,
137 false);
138 }
139
140 /**
141 * Returns the default retry policy for DynamoDB client with the specified
142 * max retry count.
143 */
144 public static RetryPolicy getDynamoDBDefaultRetryPolicyWithCustomMaxRetries(int maxErrorRetry) {
145 return new RetryPolicy(DEFAULT_RETRY_CONDITION,
146 DYNAMODB_DEFAULT_BACKOFF_STRATEGY,
147 maxErrorRetry,
148 false);
149 }
150
151 /**
152 * The default implementation of RetryCondition used by the SDK. User could
153 * extend this class to provide additional custom conditions.
154 * The default implementation checks for various conditions in
155 * the following order:
156 * <ul>
157 * <li>Retry on client exceptions caused by IOException;
158 * <li>Retry on service exceptions that are either 500 internal server
159 * errors, 503 service unavailable errors, service throttling errors or
160 * clock skew errors.
161 * </ul>
162 */
163 public static class SDKDefaultRetryCondition implements RetryPolicy.RetryCondition {
164
165 @Override
166 public boolean shouldRetry(AmazonWebServiceRequest originalRequest,
167 AmazonClientException exception,
168 int retriesAttempted) {
169 // Always retry on client exceptions caused by IOException
170 if (exception.getCause() instanceof IOException) return true;
171
172 // Only retry on a subset of service exceptions
173 if (exception instanceof AmazonServiceException) {
174 AmazonServiceException ase = (AmazonServiceException)exception;
175
176 /*
177 * For 500 internal server errors and 503 service
178 * unavailable errors, we want to retry, but we need to use
179 * an exponential back-off strategy so that we don't overload
180 * a server with a flood of retries.
181 */
182 if (RetryUtils.isRetryableServiceException(ase)) return true;
183
184 /*
185 * Throttling is reported as a 400 error from newer services. To try
186 * and smooth out an occasional throttling error, we'll pause and
187 * retry, hoping that the pause is long enough for the request to
188 * get through the next time.
189 */
190 if (RetryUtils.isThrottlingException(ase)) return true;
191
192 /*
193 * Clock skew exception. If it is then we will get the time offset
194 * between the device time and the server time to set the clock skew
195 * and then retry the request.
196 */
197 if (RetryUtils.isClockSkewError(ase)) return true;
198 }
199
200 return false;
201 }
202
203 }
204 }
205