Support retry after M_LIMIT_EXCEEDED

This commit is contained in:
Valere 2021-02-25 00:17:27 +01:00
parent 4b27ad8ba6
commit 6c69a6055d
3 changed files with 29 additions and 5 deletions

View file

@ -37,7 +37,8 @@ internal data class ConfigurableTask<PARAMS, RESULT>(
val id: UUID, val id: UUID,
val callbackThread: TaskThread, val callbackThread: TaskThread,
val executionThread: TaskThread, val executionThread: TaskThread,
val callback: MatrixCallback<RESULT> val callback: MatrixCallback<RESULT>,
val maxRetryCount: Int = 0
) : Task<PARAMS, RESULT> by task { ) : Task<PARAMS, RESULT> by task {
@ -57,7 +58,8 @@ internal data class ConfigurableTask<PARAMS, RESULT>(
id = id, id = id,
callbackThread = callbackThread, callbackThread = callbackThread,
executionThread = executionThread, executionThread = executionThread,
callback = callback callback = callback,
maxRetryCount = retryCount
) )
} }

View file

@ -16,7 +16,29 @@
package org.matrix.android.sdk.internal.task package org.matrix.android.sdk.internal.task
import kotlinx.coroutines.delay
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.shouldBeRetried
import timber.log.Timber
internal interface Task<PARAMS, RESULT> { internal interface Task<PARAMS, RESULT> {
suspend fun execute(params: PARAMS): RESULT suspend fun execute(params: PARAMS): RESULT
suspend fun executeRetry(params: PARAMS, remainingRetry: Int) : RESULT {
return try {
execute(params)
} catch (failure: Throwable) {
if (failure.shouldBeRetried() && remainingRetry > 0) {
Timber.d(failure, "## TASK: Retriable error")
if (failure is Failure.ServerError) {
val waitTime = failure.error.retryAfterMillis ?: 0L
Timber.d(failure, "## TASK: Quota wait time $waitTime")
delay(waitTime + 100)
}
return executeRetry(params, remainingRetry - 1)
}
throw failure
}
}
} }

View file

@ -40,9 +40,9 @@ internal class TaskExecutor @Inject constructor(private val coroutineDispatchers
.launch(task.callbackThread.toDispatcher()) { .launch(task.callbackThread.toDispatcher()) {
val resultOrFailure = runCatching { val resultOrFailure = runCatching {
withContext(task.executionThread.toDispatcher()) { withContext(task.executionThread.toDispatcher()) {
Timber.v("Enqueue task $task") Timber.v("## TASK: Enqueue task $task")
Timber.v("Execute task $task on ${Thread.currentThread().name}") Timber.v("## TASK: Execute task $task on ${Thread.currentThread().name}")
task.execute(task.params) task.executeRetry(task.params, task.maxRetryCount)
} }
} }
resultOrFailure resultOrFailure