-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
41e436f
commit 24d5802
Showing
5 changed files
with
113 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Retry | ||
================ | ||
|
||
En dingseboms som retryer ting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dependencies { | ||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") | ||
} |
33 changes: 33 additions & 0 deletions
33
retry/src/main/kotlin/com/github/navikt/tbd_libs/retry/Retry.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.github.navikt.tbd_libs.retry | ||
|
||
import kotlinx.coroutines.CancellationException | ||
import kotlinx.coroutines.delay | ||
import kotlinx.coroutines.runBlocking | ||
import java.time.Duration | ||
import java.time.Duration.ofMillis | ||
|
||
suspend inline fun <T> retry( | ||
utsettelser: Iterator<Duration> = DefaultUtsettelser(), | ||
avbryt: (throwable: Throwable) -> Boolean = { false }, | ||
block: () -> T | ||
): T { | ||
while (utsettelser.hasNext()) { | ||
try { return block() } catch (t: Throwable) { | ||
if (t is CancellationException || avbryt(t)) throw t | ||
} | ||
delay(utsettelser.next().toMillis()) | ||
} | ||
return block() | ||
} | ||
|
||
inline fun <T> retryBlocking( | ||
utsettelser: Iterator<Duration> = DefaultUtsettelser(), | ||
crossinline avbryt: (throwable: Throwable) -> Boolean = { false }, | ||
crossinline block: () -> T | ||
) = runBlocking { retry(utsettelser, avbryt, block) } | ||
|
||
class DefaultUtsettelser: Iterator<Duration> { | ||
private val utsettelser = mutableListOf(ofMillis(200), ofMillis(600), ofMillis(1200)) | ||
override fun hasNext() = utsettelser.isNotEmpty() | ||
override fun next(): Duration = utsettelser.removeAt(0) | ||
} |
72 changes: 72 additions & 0 deletions
72
retry/src/test/kotlin/com/github/navikt/tbd_libs/retry/RetryTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package com.github.navikt.tbd_libs.retry | ||
|
||
import kotlinx.coroutines.delay | ||
import kotlinx.coroutines.runBlocking | ||
import org.junit.jupiter.api.Assertions.assertEquals | ||
import org.junit.jupiter.api.Test | ||
import org.junit.jupiter.api.assertThrows | ||
|
||
internal class RetryTest { | ||
|
||
@Test | ||
fun `Først en test av dingsen`() { | ||
val dings = DingsSomFunkerPåForsøk(4) | ||
assertEquals("En feil på forsøk 1", assertThrows<IllegalStateException> { dings.gjørtingBlocking() }.message) | ||
assertEquals("En feil på forsøk 2", assertThrows<IllegalStateException> { dings.gjørtingBlocking() }.message) | ||
assertEquals("En feil på forsøk 3", assertThrows<IllegalStateException> { dings.gjørtingBlocking() }.message) | ||
assertEquals("Det gikk jo bra på førsøk 4 da", dings.gjørtingBlocking()) | ||
} | ||
|
||
@Test | ||
fun `Når noe funker med en gang`() { | ||
val dings = DingsSomFunkerPåForsøk(1) | ||
assertEquals("Det gikk jo bra på førsøk 1 da", retryBlocking { dings.gjørtingBlocking() }) | ||
} | ||
|
||
@Test | ||
fun `Når noe funker med på førsøk 3`() { | ||
val dings = DingsSomFunkerPåForsøk(3) | ||
assertEquals("Det gikk jo bra på førsøk 3 da", retryBlocking { dings.gjørtingBlocking() }) | ||
} | ||
|
||
@Test | ||
fun `Når noe feiler 4 ganger og vi ikke prøver noe mer`() { | ||
val dings = DingsSomFunkerPåForsøk(5) | ||
assertEquals("En feil på forsøk 4", assertThrows<IllegalStateException> { retryBlocking { dings.gjørtingBlocking() } }.message) | ||
} | ||
|
||
@Test | ||
fun `Om det er en spesiell feil som vi ikke vil retrye på så fortsetter vi ei`() { | ||
val dings = DingsSomFunkerPåForsøk(10, feil = { EnfeilViIkkeVilRetrye(it) }) | ||
assertEquals( | ||
"For dette her fikses ikke av en retry. Så derfor feiler vi på forsøk 1", | ||
assertThrows<IllegalStateException> { retryBlocking(avbryt = { it is EnfeilViIkkeVilRetrye} ) { dings.gjørtingBlocking() } }.message | ||
) | ||
} | ||
|
||
@Test | ||
fun `Når noe funker med på førsøk 3 suspendable`() = runBlocking { | ||
val dings = DingsSomFunkerPåForsøk(3) | ||
assertEquals("Det gikk jo bra på førsøk 3 da", retry { dings.gjørting() }) | ||
} | ||
|
||
private class DingsSomFunkerPåForsøk( | ||
private val forsøk: Int, | ||
private val feil: (nåværendeForsøk: Int) -> Throwable = { IllegalStateException("En feil på forsøk $it") } | ||
) { | ||
init { check(forsøk >= 1) } | ||
private var nåværendeForsøk = 1 | ||
|
||
fun gjørtingBlocking(): String { | ||
if (nåværendeForsøk == forsøk) return "Det gikk jo bra på førsøk $nåværendeForsøk da" | ||
throw feil(nåværendeForsøk++) | ||
} | ||
suspend fun gjørting(): String { | ||
delay(1) | ||
return gjørtingBlocking() | ||
} | ||
|
||
} | ||
|
||
private class EnfeilViIkkeVilRetrye(nåværendeForsøk: Int): IllegalStateException("For dette her fikses ikke av en retry. Så derfor feiler vi på forsøk $nåværendeForsøk") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
rootProject.name = "tbd-libs" | ||
include("azure-token-client", "azure-token-client-default", "mock-http-client", "minimal-sts-client", "minimal-soap-client", "postgres-testdatabaser") | ||
include("azure-token-client", "azure-token-client-default", "mock-http-client", "minimal-sts-client", "minimal-soap-client", "postgres-testdatabaser", "retry") |