Skip to content

Instantly share code, notes, and snippets.

@TemMax
Last active January 7, 2021 12:35
Show Gist options
  • Save TemMax/afe105ec1324259970bfbb7a30a5d91f to your computer and use it in GitHub Desktop.
Save TemMax/afe105ec1324259970bfbb7a30a5d91f to your computer and use it in GitHub Desktop.
A function that wraps another suspend function for exponential retry
/**
* A function that wraps another suspend function for exponential retry
*
* @param count number of retires
* @param initialDelay millis between retries
* @param maxDelay max millis of delay from exponential backoff strategy
* @param factor delay multiplier
* @param predicate true — need continue retries, false — rethrows Throwable to caller
* @param block function to execute
*
* @return result of block() parameter
*/
suspend fun <T> retry(
count: Int,
initialDelay: Long = 100L,
maxDelay: Long = 1000L,
factor: Float = 2.0F,
predicate: (cause: Throwable) -> Boolean = { true },
block: suspend () -> T
): T {
require(count > 0) { "Count must be > 0" }
require(initialDelay > 0L) { "Delay must be > 0" }
require(maxDelay >= initialDelay) { "Max delay must be >= Delay" }
require(factor > 1F) { "Factor must be > 1" }
var currentDelay = initialDelay
repeat(count - 1) {
try {
return block()
} catch (e: Exception) {
if (predicate(e)) {
delay(currentDelay)
currentDelay = (currentDelay * factor).toLong().coerceAtMost(maxDelay)
} else {
throw e
}
}
}
return block()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment