All Projects → michaelbull → Kotlin Retry

michaelbull / Kotlin Retry

Licence: isc
A higher-order function for retrying operations that may fail.

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to Kotlin Retry

Monio
Async-capable IO monad for JS
Stars: ✭ 311 (+95.6%)
Mutual labels:  io, functional-programming
Helios
A purely functional JSON library for Kotlin built on Λrrow
Stars: ✭ 157 (-1.26%)
Mutual labels:  functional-programming
Rangeless
c++ LINQ -like library of higher-order functions for data manipulation
Stars: ✭ 148 (-6.92%)
Mutual labels:  functional-programming
Mvi Archtecture
The practice of MVI + Jetpack architecture in Android.
Stars: ✭ 152 (-4.4%)
Mutual labels:  functional-programming
Cube Composer
A puzzle game inspired by functional programming
Stars: ✭ 1,845 (+1060.38%)
Mutual labels:  functional-programming
L1
L1: Tensor Studio — The playground for tensors
Stars: ✭ 154 (-3.14%)
Mutual labels:  functional-programming
Typelang
🌳 A tiny language interpreter implemented purely in TypeScript's type-system
Stars: ✭ 149 (-6.29%)
Mutual labels:  functional-programming
Dslsofmath
Domain Specific Languages of Mathematics
Stars: ✭ 159 (+0%)
Mutual labels:  functional-programming
Ofxgpio
Library C++ for raspberrypi and orangepi, GPIO interfaces compatible with openframeworks.
Stars: ✭ 155 (-2.52%)
Mutual labels:  io
Pyfunctional
Python library for creating data pipelines with chain functional programming
Stars: ✭ 1,943 (+1122.01%)
Mutual labels:  functional-programming
Easysequence
EasySequence is a powerful fundamental library to process sequcence type, such as array, set, dictionary. All type object which conforms to NSFastEnumeration protocol can be initialzed to an EZSequence instance, then you can operation with them. Finally, you can transfer them back to the original type.
Stars: ✭ 150 (-5.66%)
Mutual labels:  functional-programming
Meow Mtl
Next Level MTL for Scala
Stars: ✭ 149 (-6.29%)
Mutual labels:  functional-programming
Boson
A C++14 framework for asynchronous I/O, cooperative multitasking and green threads scheduling
Stars: ✭ 154 (-3.14%)
Mutual labels:  io
Doobie
Functional JDBC layer for Scala.
Stars: ✭ 1,910 (+1101.26%)
Mutual labels:  functional-programming
Kotlindiscretemathtoolkit
Set of extensions for Kotlin that provides Discrete math functionalities
Stars: ✭ 158 (-0.63%)
Mutual labels:  functional-programming
Munus
Power of object-oriented programming with the elegance of functional programming in PHP.
Stars: ✭ 149 (-6.29%)
Mutual labels:  functional-programming
Evilml
A compiler from ML to C++ template language
Stars: ✭ 149 (-6.29%)
Mutual labels:  functional-programming
Fs2
Compositional, streaming I/O library for Scala
Stars: ✭ 1,998 (+1156.6%)
Mutual labels:  functional-programming
Metalang99
A functional language for C99 preprocessor metaprogramming
Stars: ✭ 152 (-4.4%)
Mutual labels:  functional-programming
Category Theory For Dotnet Programmers
This repo contains all c++ / haskell samples from Bartosz Milewski's book (Category Theory for Programmers) converted to csharp and fsharp
Stars: ✭ 159 (+0%)
Mutual labels:  functional-programming

kotlin-retry

Maven Central CI Status License

retry is a higher-order function for retrying operations that may fail.

retry(limitAttempts(10) + constantDelay(delayMillis = 50L)) {
    /* your code */
}

Installation

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.michael-bull.kotlin-retry:kotlin-retry:1.0.8")
}

Introduction

IO operations often experience temporary failures that warrant re-execution, e.g. a database transaction that may fail due to a deadlock.[1][2]

“even if your application logic is correct, you must still handle the case where a transaction must be retried”

Deadlocks in InnoDB

The retry function simplifies this process by wrapping the application logic and applying a specified RetryPolicy.

In the example below, either of the calls to customers.nameFromId may fail, abandoning the remaining logic within the printExchangeBetween function. As such, we may want to retry this operation until 5 attempts in total have been executed:

import com.github.michaelbull.retry.policy.limitAttempts
import com.github.michaelbull.retry.retry
import kotlinx.coroutines.runBlocking

suspend fun printExchangeBetween(a: Long, b: Long) {
    val customer1 = customers.nameFromId(a)
    val customer2 = customers.nameFromId(b)
    println("$customer1 exchanged with $customer2")
}

fun main() = runBlocking {
    retry(limitAttempts(5)) {
        printExchangeBetween(1L, 2L)
    }
}

We can also provide a RetryPolicy that only retries failures of a specific type. The example below will retry the operation only if the reason for failure was a SQLDataException, pausing for 20 milliseconds before retrying and stopping after 5 total attempts.

import com.github.michaelbull.retry.ContinueRetrying
import com.github.michaelbull.retry.StopRetrying
import com.github.michaelbull.retry.policy.RetryPolicy
import com.github.michaelbull.retry.policy.constantDelay
import com.github.michaelbull.retry.policy.limitAttempts
import com.github.michaelbull.retry.policy.plus
import com.github.michaelbull.retry.retry
import kotlinx.coroutines.runBlocking
import java.sql.SQLDataException

val retryTimeouts: RetryPolicy<Throwable> = {
    if (reason is SQLDataException) ContinueRetrying else StopRetrying
}

suspend fun printExchangeBetween(a: Long, b: Long) {
    val customer1 = customers.nameFromId(a)
    val customer2 = customers.nameFromId(b)
    println("$customer1 exchanged with $customer2")
}

fun main() = runBlocking {
    retry(retryTimeouts + limitAttempts(5) + constantDelay(20)) {
        printExchangeBetween(1L, 2L)
    }
}

Backoff

The examples above retry executions immediately after they fail, however we may wish to spread out retries with an ever-increasing delay. This is known as a "backoff" and comes in many forms. This library includes all the forms of backoff strategy detailed the article by Marc Brooker on the AWS Architecture Blog entitled "Exponential Backoff And Jitter".

Binary Exponential

“exponential backoff means that clients multiply their backoff by a constant after each attempt, up to some maximum value”

sleep = min(cap, base * 2 ** attempt)
retry(limitAttempts(5) + binaryExponentialBackoff(base = 10L, max = 5000L)) {
    /* code */
}

Full Jitter

“trying to improve the performance of a system by adding randomness ... we want to spread out the spikes to an approximately constant rate”

sleep = random_between(0, min(cap, base * 2 ** attempt))
retry(limitAttempts(5) + fullJitterBackoff(base = 10L, max = 5000L)) {
    /* code */
}

Equal Jitter

“Equal Jitter, where we always keep some of the backoff and jitter by a smaller amount”

temp = min(cap, base * 2 ** attempt)
sleep = temp / 2 + random_between(0, temp / 2)
retry(limitAttempts(5) + equalJitterBackoff(base = 10L, max = 5000L)) {
    /* code */
}

Decorrelated Jitter

“Decorrelated Jitter, which is similar to “Full Jitter”, but we also increase the maximum jitter based on the last random value”

sleep = min(cap, random_between(base, sleep * 3))
retry(limitAttempts(5) + decorrelatedJitterBackoff(base = 10L, max = 5000L)) {
    /* code */
}

Inspiration

Contributing

Bug reports and pull requests are welcome on GitHub.

License

This project is available under the terms of the ISC license. See the LICENSE file for the copyright information and licensing terms.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].