-
-
Save arbal/95991a8cc55a8637623d8d7fe336bf29 to your computer and use it in GitHub Desktop.
Bash retry function with exponential backoff.
This file contains hidden or 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
#!/usr/bin/env bash | |
# This software is freely available under the Apache 2.0 license. | |
# Full license available here: https://www.apache.org/licenses/LICENSE-2.0.txt | |
set -o errexit | |
set -o nounset | |
set -o pipefail | |
# Retry a command on a particular exit code, up to a max number of attempts, | |
# with exponential backoff. | |
# Invocation: | |
# err_retry exit_code attempts sleep_multiplier <command> | |
# exit_code: The exit code to retry on. | |
# attempts: The number of attempts to make. | |
# sleep_millis: Multiplier for sleep between attempts. Examples: | |
# If multiplier is 1000, sleep intervals are 1, 2, 4, 8, 16, etc. seconds. | |
# If multiplier is 5000, sleep intervals are 5, 10, 20, 40, 80, etc. seconds. | |
function err_retry() { | |
local exit_code=$1 | |
local attempts=$2 | |
local sleep_millis=$3 | |
shift 3 | |
for attempt in `seq 1 $attempts`; do | |
if [[ $attempt -gt 1 ]]; then | |
echo "Attempt $attempt of $attempts" | |
fi | |
# This weird construction lets us capture return codes under -o errexit | |
"$@" && local rc=$? || local rc=$? | |
if [[ ! $rc -eq $exit_code ]]; then | |
return $rc | |
fi | |
if [[ $attempt -eq $attempts ]]; then | |
return $rc | |
fi | |
local sleep_ms="$(($attempt * $attempt * $sleep_millis))" | |
sleep "${sleep_ms:0:-3}.${sleep_ms: -3}" | |
done | |
} | |
## Basic tests. | |
function arg_fail() { | |
echo $2 | |
return $1 | |
} | |
err_retry 2 5 100 arg_fail 2 "fail" || true | |
err_retry 2 5 1 arg_fail 1 "other_fail" || true | |
err_retry 2 5 1 arg_fail 0 "succeed" || true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment