Bash で雑に Exponential Backoff したくなって作ったので書いておく。
実装
exponential_backoff.sh
#!/bin/bash -eu
if [ $# -eq 0 ]; then
echo -e "Usage:\n ${0} command"
exit 1
fi
for((i=0;;i++)); do
$@
[ $? -eq 0 ] && exit
echo "command execution failed"
echo "wait $((2**i)) seconds and retry"
sleep $((2**i))
done
終了コードが 0 以外なら sleep してリトライするだけの素朴な実装。
使い方
リトライしたいコマンドの例として「[0-9]の終了コードをランダムに返す (10回に1回くらい成功する) スクリプト」を用意。
command.sh
#!/bin/bash -eu
code=$(($RANDOM % 10))
echo "status code: ${code}"
exit ${code}
exponential_backoff.sh
を使って実行する。
$ ./exponential_backoff.sh ./command.sh
status code: 7
command execution failed
wait 1 seconds and retry
status code: 1
command execution failed
wait 2 seconds and retry
status code: 3
command execution failed
wait 4 seconds and retry
status code: 7
command execution failed
wait 8 seconds and retry
status code: 4
command execution failed
wait 16 seconds and retry
status code: 0
備考
ポートフォワーディングしている SSH 接続が切れたらリトライしたくて書いたけど、そんなことするより autossh 使ったほうが早い。