Releases: michaelbull/kotlin-retry
2.0.2
2.0.1
This release introduces the kotlin-retry-result subproject, leveraging the Result<V, E> type from kotlin-result for code that must be retried but returns an Err instead of throwing an Exception.
See the README section for a full example.
To install the new extension library:
repositories {
mavenCentral()
}
dependencies {
implementation("com.michael-bull.kotlin-retry:kotlin-retry:2.0.1")
implementation("com.michael-bull.kotlin-retry:kotlin-retry-result:2.0.1")
}2.0.0
Version 2.0.0 represents a major breaking change in the form of an underlying rewrite and support for all three tiers of Kotlin/Native.
Multiplatform
The project has been converted to be multiplatform, matching compatibility with kotlinx-coroutines support for all three tiers of Kotlin/Native.
The full list of platform targets can be found in the kotlin-conventions Gradle plugin.
Policy Authoring Changes
The implementation no longer relies on CoroutineContext to persist the state of retry attempts. Instead, the RetryPolicy (now a functional interface) is passed the attempt that just failed. This makes it clear on the callsite what information about the failed attempt is available, instead of being expected to know what fields are in the coroutineContext.retryStatus.
The attempt argument for a RetryPolicy contains:
- The
failureas a generic.- In the default case of invoking the
retryorrunRetryingfunction, this will beThrowable, however leaves future oppurtunity for aResult-backedretryfunction that uses anErrinstead of aThrowable.
- In the default case of invoking the
- A zero-based attempt number.
0means the invocation of theblockhas failed and no attempts have been made to retry invoking theblock.1means the invocation of theblockhas failed, and one attempt to retry invoking theblockalso failed - totalling two attempts and one retry.
- The
delaybetween the failed attempt and the attempt prior. - The
cumulativeDelayacross all attempts.
Before:
public fun binaryExponentialBackoff(min: Long, max: Long): RetryPolicy<*> {
require(min > 0) { "min must be positive, but was $min" }
require(max > 0) { "max must be positive, but was $max" }
return {
val attempt = coroutineContext.retryStatus.attempt
val delay = min(max, min saturatedMultiply attempt.binaryExponential())
RetryAfter(delay)
}
}After:
public fun <E> binaryExponentialBackoff(min: Long, max: Long): RetryPolicy<E> {
require(min > 0) { "min must be positive, but was $min" }
require(max > 0) { "max must be positive, but was $max" }
return RetryPolicy { attempt ->
val delay = min(max, min saturatedMultiply attempt.number.binaryExponential())
RetryAfter(delay)
}
}Function Changes
Various functions have been added, renamed, or their signature otherwise changed to comply with the rewrite.
Renamed
maxDelay->delayAtMostlimitAttempts->stopAtAttemptslimitByDelay->stopAtDelaylimitByCumulativeDelay->stopAtCumulativeDelayretryIf->continueIfretryUnless->continueUnless
Added
delayAtLeastdelayAtMostdelayInstopAtRetriesstopIfstopUnless
1.0.9
- Collapse multiple catch blocks for Graalvm (0c7e668) by @cherrydev
- Fixes #16
1.0.8
- Add retryUnless policy (a0b7174)
- Facilitates creating a
RetryPolicythat only retries if a given predicate is not satisfied. Analogous totakeUnlessin the stdlib.
- Facilitates creating a