-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1843 from navikt/distribusjon-retries
Legg til backoff på distribusjons-retry
- Loading branch information
Showing
21 changed files
with
465 additions
and
97 deletions.
There are no files selected for viewing
36 changes: 36 additions & 0 deletions
36
...n/domain/src/main/kotlin/no/nav/su/se/bakover/common/domain/backoff/ExponentialBackoff.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,36 @@ | ||
package no.nav.su.se.bakover.common.domain.backoff | ||
|
||
import arrow.core.Either | ||
import arrow.core.left | ||
import arrow.core.right | ||
import no.nav.su.se.bakover.common.tid.Tidspunkt | ||
import java.time.Clock | ||
import kotlin.time.Duration | ||
import kotlin.time.Duration.Companion.hours | ||
import kotlin.time.Duration.Companion.minutes | ||
|
||
fun Failures.shouldRetry( | ||
clock: Clock, | ||
delayTable: Map<Long, Duration> = mapOf( | ||
1L to 1.minutes, | ||
2L to 5.minutes, | ||
3L to 15.minutes, | ||
4L to 30.minutes, | ||
5L to 1.hours, | ||
6L to 2.hours, | ||
7L to 4.hours, | ||
8L to 8.hours, | ||
9L to 12.hours, | ||
10L to 24.hours, | ||
), | ||
maxDelay: Duration = 24.hours, | ||
): Either<Unit, Failures> { | ||
if (last == null) return this.inc(clock).right() | ||
val delayDuration = delayTable[count]?.coerceAtMost(maxDelay) ?: maxDelay | ||
val nextRetryTime = last.plus(delayDuration) | ||
return if (Tidspunkt.now(clock) >= nextRetryTime) { | ||
this.inc(clock).right() | ||
} else { | ||
Unit.left() | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
common/domain/src/main/kotlin/no/nav/su/se/bakover/common/domain/backoff/Failures.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,24 @@ | ||
package no.nav.su.se.bakover.common.domain.backoff | ||
|
||
import no.nav.su.se.bakover.common.tid.Tidspunkt | ||
import java.time.Clock | ||
|
||
/** | ||
* Oversikt over antall feil og tidspunkt for siste feil. | ||
* Typisk brukt for å vurdere om en operasjon skal prøves på nytt. | ||
*/ | ||
data class Failures( | ||
val count: Long, | ||
val last: Tidspunkt?, | ||
) { | ||
fun inc(clock: Clock): Failures { | ||
return Failures( | ||
count = count + 1, | ||
last = Tidspunkt.now(clock), | ||
) | ||
} | ||
|
||
companion object { | ||
val EMPTY = Failures(0, null) | ||
} | ||
} |
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
102 changes: 102 additions & 0 deletions
102
...main/src/test/kotlin/no/nav/su/se/bakover/common/domain/backoff/ExponentialBackoffTest.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,102 @@ | ||
package no.nav.su.se.bakover.common.domain.backoff | ||
|
||
import arrow.core.left | ||
import arrow.core.right | ||
import io.kotest.matchers.shouldBe | ||
import no.nav.su.se.bakover.common.tid.Tidspunkt | ||
import no.nav.su.se.bakover.test.fixedClock | ||
import no.nav.su.se.bakover.test.plus | ||
import org.junit.jupiter.api.Test | ||
import java.time.temporal.ChronoUnit | ||
|
||
internal class ExponentialBackoffTest { | ||
@Test | ||
fun `Should retry when empty`() { | ||
Failures.EMPTY.shouldRetry(fixedClock) shouldBe Failures( | ||
count = 1, | ||
last = Tidspunkt.now(fixedClock), | ||
).right() | ||
} | ||
|
||
@Test | ||
fun `Should not retry when 1 failure and less than a minute has passed`() { | ||
val clockBefore = fixedClock | ||
val clockAfter = clockBefore.plus(59, ChronoUnit.SECONDS) | ||
Failures( | ||
count = 1, | ||
last = Tidspunkt.now(fixedClock), | ||
).shouldRetry(clockAfter) shouldBe Unit.left() | ||
} | ||
|
||
@Test | ||
fun `Should retry when 1 failure and 1 minute has passed`() { | ||
val clockBefore = fixedClock | ||
val clockAfter = clockBefore.plus(1, ChronoUnit.MINUTES) | ||
Failures( | ||
count = 1, | ||
last = Tidspunkt.now(fixedClock), | ||
).shouldRetry(clockAfter) shouldBe Failures( | ||
count = 2, | ||
last = Tidspunkt.now(clockAfter), | ||
).right() | ||
} | ||
|
||
@Test | ||
fun `Should retry when 1 failure and more than 1 minute has passed`() { | ||
val clockBefore = fixedClock | ||
val clockAfter = clockBefore.plus(1, ChronoUnit.DAYS) | ||
Failures( | ||
count = 1, | ||
last = Tidspunkt.now(fixedClock), | ||
).shouldRetry(clockAfter) shouldBe Failures( | ||
count = 2, | ||
last = Tidspunkt.now(clockAfter), | ||
).right() | ||
} | ||
|
||
@Test | ||
fun `Should not retry when 2 failure and less than 5 minutes has passed`() { | ||
val clockBefore = fixedClock | ||
val clockAfter = clockBefore.plus(299, ChronoUnit.SECONDS) | ||
Failures( | ||
count = 2, | ||
last = Tidspunkt.now(fixedClock), | ||
).shouldRetry(clockAfter) shouldBe Unit.left() | ||
} | ||
|
||
@Test | ||
fun `Should retry when 2 failure and 5 minute has passed`() { | ||
val clockBefore = fixedClock | ||
val clockAfter = clockBefore.plus(5, ChronoUnit.MINUTES) | ||
Failures( | ||
count = 2, | ||
last = Tidspunkt.now(fixedClock), | ||
).shouldRetry(clockAfter) shouldBe Failures( | ||
count = 3, | ||
last = Tidspunkt.now(clockAfter), | ||
).right() | ||
} | ||
|
||
@Test | ||
fun `should not retry if less than max value`() { | ||
val clockBefore = fixedClock | ||
val clockAfter = clockBefore.plus(1439, ChronoUnit.MINUTES) | ||
Failures( | ||
count = 11, | ||
last = Tidspunkt.now(fixedClock), | ||
).shouldRetry(clockAfter) shouldBe Unit.left() | ||
} | ||
|
||
@Test | ||
fun `Should support retries outside Map values`() { | ||
val clockBefore = fixedClock | ||
val clockAfter = clockBefore.plus(24, ChronoUnit.HOURS) | ||
Failures( | ||
count = 11, | ||
last = Tidspunkt.now(fixedClock), | ||
).shouldRetry(clockAfter) shouldBe Failures( | ||
count = 12, | ||
last = Tidspunkt.now(clockAfter), | ||
).right() | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
database/src/main/resources/db/migration/V207__dokument_distribusjon_retries.sql
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,7 @@ | ||
ALTER TABLE dokument_distribusjon | ||
ADD COLUMN IF NOT EXISTS | ||
distribusjon_failure_count bigint not null default 0; | ||
|
||
ALTER TABLE dokument_distribusjon | ||
ADD COLUMN IF NOT EXISTS | ||
distribusjon_last_failure_timestamp timestamptz default null; |
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
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
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
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
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
Oops, something went wrong.