Skip to content

Commit

Permalink
add retry policy (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
azaka01 authored Jul 24, 2022
1 parent 4250f54 commit 238f7f6
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 5 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/java/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object Versions {
val compile_sdk = 30

// SDK version
val intsoftdev_stations_client_version = "0.50"
val intsoftdev_stations_client_version = "0.51"

// kotlin core
const val kotlin = "1.5.30"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@ internal interface DBWrapper {
fun getStationLocation(stationId: String): StationEntity?
fun insertVersion(version: VersionEntity)
fun getVersion(): VersionEntity?

fun isEmpty(): Boolean
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.intsoftdev.nrstations.common

import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.retryWhen

/**
* Retry policy with exponential backoff.
*
* delayFactor is used to multiply delayMillis to increase the delay for the next retry.
*
* For instance, given a policy with numRetries of 4, delayMillis of 400ms and delayFactor of 2:
* - first retry: effective delayMillis will be 400
* - second retry: effective delayMillis will be 800
* - third retry: effective delayMillis will be 1600
* - forth retry: effective delayMillis will be 3200
*
* If no exponential backoff is desired, set delayFactor to 1
*/
interface RequestRetryPolicy {
val numRetries: Long
val delayMillis: Long
val delayFactor: Long
}

data class DefaultRetryPolicy(
override val numRetries: Long = 4,
override val delayMillis: Long = 400,
override val delayFactor: Long = 2
) : RequestRetryPolicy


fun <T> Flow<T>.retryWithPolicy(
requestRetryPolicy: RequestRetryPolicy
): Flow<T> {
var currentDelay = requestRetryPolicy.delayMillis
val delayFactor = requestRetryPolicy.delayFactor
return retryWhen { cause, attempt ->
if (attempt < requestRetryPolicy.numRetries) {
delay(currentDelay)
currentDelay *= delayFactor
return@retryWhen true
} else {
return@retryWhen false
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import com.intsoftdev.nrstations.common.DefaultRetryPolicy
import com.intsoftdev.nrstations.data.StationsAPI
import com.intsoftdev.nrstations.data.StationsProxy
import com.intsoftdev.nrstations.data.StationsRepositoryImpl
Expand Down Expand Up @@ -31,7 +32,8 @@ internal val stationsDataModule = module {
StationsRepositoryImpl(
stationsProxyService = get(),
stationsCache = get(),
requestDispatcher = get(named("NRStationsCoroutineDispatcher"))
requestDispatcher = get(named("NRStationsCoroutineDispatcher")),
requestRetryPolicy = DefaultRetryPolicy()
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package com.intsoftdev.nrstations.data
import io.github.aakira.napier.Napier
import com.intsoftdev.nrstations.cache.CacheState
import com.intsoftdev.nrstations.cache.StationsCache
import com.intsoftdev.nrstations.common.RequestRetryPolicy
import com.intsoftdev.nrstations.common.StationLocation
import com.intsoftdev.nrstations.common.StationsResult
import com.intsoftdev.nrstations.common.StationsResultState
import com.intsoftdev.nrstations.common.retryWithPolicy
import com.intsoftdev.nrstations.data.model.station.DataVersion
import com.intsoftdev.nrstations.data.model.station.toStationLocation
import com.intsoftdev.nrstations.data.model.station.toUpdateVersion
Expand All @@ -19,7 +21,8 @@ import kotlinx.coroutines.flow.flowOn
internal class StationsRepositoryImpl(
private val stationsProxyService: StationsAPI,
private val stationsCache: StationsCache,
private val requestDispatcher: CoroutineDispatcher
private val requestDispatcher: CoroutineDispatcher,
private val requestRetryPolicy: RequestRetryPolicy
) : StationsRepository {

override fun getAllStations(): Flow<StationsResultState<StationsResult>> =
Expand All @@ -39,7 +42,7 @@ internal class StationsRepositoryImpl(
)
}
}
}.catch { throwable ->
}.retryWithPolicy(requestRetryPolicy).catch { throwable ->
emit(StationsResultState.Failure(throwable))
}.flowOn(requestDispatcher)

Expand Down

0 comments on commit 238f7f6

Please sign in to comment.