Backoff: Python function decorators for configurable backoff and retry
github.com
github.com
http://riprova.readthedocs.io/en/latest/ https://github.com/h2non/riprova
Usage:
retry_unreliable(3){
sh "essential_but_unreliable_thing --failure-probability 0.01"
}
Definition: def retry_unreliable(int max_attempts, Closure func) {
def error = null
assert max_attempts > 0
def delay_initial = 8.0f
def delay_multiplier = 2.0f
def delay = delay_initial
for (attempt = 0; attempt < max_attempts; attempt++) {
if (error) {
sleep(delay)
delay = delay_multiplier * delay
}
try {
func.call()
error = null
break
} catch (e) {
error = e
println("Unreliable operation failed during attempt ${attempt+1}/${max_attempts}:")
println(e.toString());
}
}
if (error) {
println("Unreliable operation failed repeatedly for ${max_attempts}/${max_attempts} attempts. Gave up")
throw error
}
}
Sometimes doing something like this isn't necessarily the right course of action -- e.g. if an external service you depend on is struggling to reply to your requests because of load, hammering it with additional requests when it starts to fail isn't the right solution. But quite a lot of time ladling on stupid retry logic turns an irritating rare failure case into a non-issue.