Better handling on 429
This commit is contained in:
parent
1f2d6bea21
commit
0bc864fc37
@ -37,6 +37,18 @@ fun Throwable.shouldBeRetried(): Boolean {
|
|||||||
|| (this is Failure.ServerError && error.code == MatrixError.M_LIMIT_EXCEEDED)
|
|| (this is Failure.ServerError && error.code == MatrixError.M_LIMIT_EXCEEDED)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the retry delay in case of rate limit exceeded error, adding 100 ms, of defaultValue otherwise
|
||||||
|
*/
|
||||||
|
fun Throwable.getRetryDelay(defaultValue: Long): Long {
|
||||||
|
return (this as? Failure.ServerError)
|
||||||
|
?.error
|
||||||
|
?.takeIf { it.code == MatrixError.M_LIMIT_EXCEEDED }
|
||||||
|
?.retryAfterMillis
|
||||||
|
?.plus(100L)
|
||||||
|
?: defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
fun Throwable.isInvalidPassword(): Boolean {
|
fun Throwable.isInvalidPassword(): Boolean {
|
||||||
return this is Failure.ServerError
|
return this is Failure.ServerError
|
||||||
&& error.code == MatrixError.M_FORBIDDEN
|
&& error.code == MatrixError.M_FORBIDDEN
|
||||||
|
@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.network
|
|||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import org.matrix.android.sdk.api.failure.Failure
|
import org.matrix.android.sdk.api.failure.Failure
|
||||||
|
import org.matrix.android.sdk.api.failure.getRetryDelay
|
||||||
import org.matrix.android.sdk.api.failure.shouldBeRetried
|
import org.matrix.android.sdk.api.failure.shouldBeRetried
|
||||||
import org.matrix.android.sdk.internal.network.ssl.CertUtil
|
import org.matrix.android.sdk.internal.network.ssl.CertUtil
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
@ -68,8 +69,9 @@ internal suspend inline fun <DATA> executeRequest(globalErrorReceiver: GlobalErr
|
|||||||
?.also { unrecognizedCertificateException -> throw unrecognizedCertificateException }
|
?.also { unrecognizedCertificateException -> throw unrecognizedCertificateException }
|
||||||
|
|
||||||
if (canRetry && currentRetryCount++ < maxRetriesCount && exception.shouldBeRetried()) {
|
if (canRetry && currentRetryCount++ < maxRetriesCount && exception.shouldBeRetried()) {
|
||||||
delay(currentDelay)
|
// In case of 429, ensure we wait enough
|
||||||
currentDelay = (currentDelay * 2L).coerceAtMost(maxDelayBeforeRetry)
|
delay(currentDelay.coerceAtLeast(exception.getRetryDelay(0)))
|
||||||
|
currentDelay = currentDelay.times(2L).coerceAtMost(maxDelayBeforeRetry)
|
||||||
// Try again (loop)
|
// Try again (loop)
|
||||||
} else {
|
} else {
|
||||||
throw when (exception) {
|
throw when (exception) {
|
||||||
|
@ -24,6 +24,7 @@ import kotlinx.coroutines.withContext
|
|||||||
import org.matrix.android.sdk.api.auth.data.SessionParams
|
import org.matrix.android.sdk.api.auth.data.SessionParams
|
||||||
import org.matrix.android.sdk.api.failure.Failure
|
import org.matrix.android.sdk.api.failure.Failure
|
||||||
import org.matrix.android.sdk.api.failure.MatrixError
|
import org.matrix.android.sdk.api.failure.MatrixError
|
||||||
|
import org.matrix.android.sdk.api.failure.getRetryDelay
|
||||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.util.Cancelable
|
import org.matrix.android.sdk.api.util.Cancelable
|
||||||
@ -148,8 +149,7 @@ internal class EventSenderProcessorCoroutine @Inject constructor(
|
|||||||
task.markAsFailedOrRetry(exception, 0)
|
task.markAsFailedOrRetry(exception, 0)
|
||||||
}
|
}
|
||||||
(exception is Failure.ServerError && exception.error.code == MatrixError.M_LIMIT_EXCEEDED) -> {
|
(exception is Failure.ServerError && exception.error.code == MatrixError.M_LIMIT_EXCEEDED) -> {
|
||||||
val delay = exception.error.retryAfterMillis?.plus(100) ?: 3_000
|
task.markAsFailedOrRetry(exception, exception.getRetryDelay(3_000))
|
||||||
task.markAsFailedOrRetry(exception, delay)
|
|
||||||
}
|
}
|
||||||
exception is CancellationException -> {
|
exception is CancellationException -> {
|
||||||
Timber.v("## $task has been cancelled, try next task")
|
Timber.v("## $task has been cancelled, try next task")
|
||||||
|
Loading…
Reference in New Issue
Block a user