Last active
April 3, 2024 00:17
-
-
Save Demeter/4938bac9c963c4e16604 to your computer and use it in GitHub Desktop.
Implement an incremental delay for polling status, in context of cloud.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Error Retries and Exponential Backoff in AWS | |
see http://docs.aws.amazon.com/general/latest/gr/api-retries.html for context. | |
Numerous components on a network, such as DNS servers, switches, load balancers, and others can generate | |
errors anywhere in the life of a given request. The usual technique for dealing with these error responses | |
in a networked environment is to implement retries in the client application. This technique increases the | |
reliability of the application and reduces operational costs for the developer. | |
Each AWS SDK implements automatic retry logic. The AWS SDK for Java automatically retries requests, and you | |
can configure the retry settings using the ClientConfiguration class. For example, in some cases, such as | |
a web page making a request with minimal latency and no retries, you might want to turn off the retry logic. | |
Use the ClientConfiguration class and provide a maxErrorRetry value of 0 to turn off the retries. | |
If you're not using an AWS SDK, you should retry original requests that receive server (5xx) or throttling | |
errors. However, client errors (4xx) indicate you need to revise the request itself to correct the problem | |
before trying again. | |
In addition to simple retries, we recommend using an exponential backoff algorithm for better flow control. | |
The idea behind exponential backoff is to use progressively longer waits between retries for consecutive | |
error responses. You should implement a maximum delay interval, as well as a maximum number of retries. The | |
maximum delay interval and maximum number of retries are not necessarily fixed values, and should be set based | |
on the operation being performed, as well as other local factors, such as network latency. | |
Most exponential backoff algorithms make use of a random number to prevent successive collisions. Because you | |
aren't trying to avoid such collisions in these cases, you do not need to use this random number. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public enum Results { | |
SUCCESS, | |
NOT_READY, | |
THROTTLED, | |
SERVER_ERROR | |
} | |
/* | |
* Performs an asynchronous operation, then polls for the result of the | |
* operation using an incremental delay. | |
*/ | |
public static void doOperationAndWaitForResult() { | |
try { | |
// Do some asynchronous operation. | |
long token = asyncOperation(); | |
int retries = 0; | |
boolean retry = false; | |
do { | |
long waitTime = Math.min(getWaitTimeExp(retries), MAX_WAIT_INTERVAL); | |
System.out.print(waitTime + "\n"); | |
// Wait for the result. | |
Thread.sleep(waitTime); | |
// Get the result of the asynchronous operation. | |
Results result = getAsyncOperationResult(token); | |
if (Results.SUCCESS == result) { | |
retry = false; | |
} else if (Results.NOT_READY == result) { | |
retry = true; | |
} else if (Results.THROTTLED == result) { | |
retry = true; | |
} else if (Results.SERVER_ERROR == result) { | |
retry = true; | |
} | |
else { | |
// Some other error occurred, so stop calling the API. | |
retry = false; | |
} | |
} while (retry && (retries++ < MAX_RETRIES)); | |
} | |
catch (Exception ex) { | |
} | |
} | |
/* | |
* Returns the next wait interval, in milliseconds, using an exponential | |
* backoff algorithm. | |
*/ | |
public static long getWaitTimeExp(int retryCount) { | |
long waitTime = ((long) Math.pow(2, retryCount) * 100L); | |
return waitTime; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Do some asynchronous operation. */ | |
retries = 0 | |
DO | |
wait for (2^retries * 100) milliseconds | |
status = Get the result of the asynchronous operation. | |
IF status = SUCCESS | |
retry = false | |
ELSE IF status = NOT_READY | |
retry = true | |
ELSE IF status = THROTTLED | |
retry = true | |
ELSE | |
Some other error occurred, so stop calling the API. | |
retry = false | |
END IF | |
retries = retries + 1 | |
WHILE (retry AND (retries < MAX_RETRIES)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Reduce error retries using exponential back off. Implement this by polling for status using an incremental delay.