Closed WingSafari5 closed 3 years ago
The @Retry
and @Cache
annotations were deprecated and removed a while ago.
One way to repeat calls is to use the retrofitCall
suspend function CoroutineHelper. You can pass a renewFun
and a retryCount
(set it to Int.MAX_VALUE - 1
)
But in my opinion, the best way to achieve your goal is to write your own coroutine. Something like this (inside a ViewModel):
fun makeCall(payload: Int): {
viewModelScope.launch {
while (coroutineContext.isActive) {
retrofitCall {
MyApi.submitValue(payload)
}.success {
//use `data` here
cancel()
}.noSuccess {
when (code) {
500 -> TODO()
else -> TODO()
}
}.error {
Timber.w(throwable)
}
}
}
}
The interface MyApi
could be generated with OpenAPI Kgen. I wrote this generator to generate easy to use retrofit modules. Generated Example
Also, Kotlin Flows should work for you. Especially SharedFlow
/ MutableSharedFlow
.
Another approach would be to use a worker and set the constraints to only run when a network connection is available. Workers will automatically retry if your return Result.retry()
in your doWork()
method. This would work best in combination with a database to store the result. You could observe the results with LiveData.
class MyWorker @WorkerInject constructor(
@Assisted context: Context,
@Assisted workerParams: WorkerParameters,
private val repo: Repository
) : CoroutineWorker(context, workerParams) {
override suspend fun doWork(): Result {
Timber.d("doWork()")
val success = repo.fetchAndStore()
Timber.d("success: $success")
return if (success) Result.success() else Result.retry()
}
companion object {
fun enqueue(context: Context) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val work = PeriodicWorkRequestBuilder<MyWorker >(
5, TimeUnit.MINUTES,
1, TimeUnit.MINUTES
)
.addTag("my.worker")
.setConstraints(constraints)
.setBackoffCriteria(BackoffPolicy.LINEAR, 1, TimeUnit.MINUTES)
.build()
Timber.d("enqueue MyWorker: $constraints $work")
WorkManager.getInstance(context).enqueueUniquePeriodicWork(Const.WORKER_NAME, ExistingPeriodicWorkPolicy.REPLACE, work)
}
}
}
Thank you for your excellent answer. So the answeris to write my own. Thanks! I was really hoping someone else had already written a retry lib which would survive restarts of the process...
Can this library be used to
@Retry
an infinity amount of time until the server sends some sort of response (maybe 500 response allowed too)?It would be very helpful to me if I could retry a call until it reaches the server. Ideally it would only retry when the OS transmits a status about available internet.
My goal is to cache "change requests" made via REST (e. g. change warehouse item amount from 7 to 5) and to retransmit them until the backend takes them.
It's not clear from the readme weather this is a goal or a non-goal.
I found out about this lib via this reddit thread.