Skip to content

Instantly share code, notes, and snippets.

@fernandoacorreia
Last active November 26, 2019 13:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fernandoacorreia/b4fa9ae88c67fa6759d271b743e96063 to your computer and use it in GitHub Desktop.
Save fernandoacorreia/b4fa9ae88c67fa6759d271b743e96063 to your computer and use it in GitHub Desktop.
Retries a command a with backoff
#!/bin/bash
set -o nounset -o errexit -o pipefail
# Retries a command a with backoff.
# Based on https://stackoverflow.com/a/8351489/376366
# and https://gist.github.com/fernandoacorreia/b4fa9ae88c67fa6759d271b743e96063
#
# The retry count is given by ATTEMPTS (default 7), the
# initial backoff timeout is given by TIMEOUT in seconds
# (default 1). With default settings, it will try for about 1 minute.
#
# Successive backoffs double the timeout.
function with_backoff {
local max_attempts=${ATTEMPTS-7}
local timeout=${TIMEOUT-1}
local attempt=1
local exitCode=0
while (( $attempt < $max_attempts ))
do
set +e
"$@"
exitCode=$?
set -e
if [[ $exitCode == 0 ]]
then
break
fi
echo "Attempt $attempt/$max_attempts failed ($@). Retrying in ${timeout}s..." 1>&2
sleep $timeout
attempt=$(( attempt + 1 ))
timeout=$(( timeout * 2 ))
done
if [[ $exitCode != 0 ]]
then
echo "Attempt $attempt/$max_attempts failed ($@). Maximum retries exceeded." 1>&2
fi
return $exitCode
}
IS_A_RETRY="NO"
function test_it()
{
if [ "$IS_A_RETRY" == "YES" ]; then
true
else
IS_A_RETRY="YES"
false
fi
}
echo "Will succeed the first time:"
with_backoff true
echo "Will succeed the second time:"
with_backoff test_it
echo "Will fail:"
with_backoff false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment