Don't re-schedule notification fetches if the cause of the failure is SessionRestorationException, since that means it'll most likely fail again
This commit is contained in:
parent
f745f2ca1e
commit
754c0781f9
3 changed files with 17 additions and 6 deletions
|
|
@ -10,7 +10,11 @@ package io.element.android.libraries.matrix.api.exception
|
||||||
|
|
||||||
sealed class ClientException(message: String, val details: String?, cause: Throwable? = null) : Exception(message, cause) {
|
sealed class ClientException(message: String, val details: String?, cause: Throwable? = null) : Exception(message, cause) {
|
||||||
class Generic(message: String, details: String?, cause: Throwable? = null) : ClientException(message, details, cause)
|
class Generic(message: String, details: String?, cause: Throwable? = null) : ClientException(message, details, cause)
|
||||||
class MatrixApi(val kind: ErrorKind, val code: String, message: String, details: String?, cause: Throwable? = null) : ClientException(message, details, cause)
|
class MatrixApi(val kind: ErrorKind, val code: String, message: String, details: String?, cause: Throwable? = null) : ClientException(
|
||||||
|
message = message,
|
||||||
|
details = details,
|
||||||
|
cause = cause
|
||||||
|
)
|
||||||
class Other(message: String, cause: Throwable? = null) : ClientException(message, null, cause)
|
class Other(message: String, cause: Throwable? = null) : ClientException(message, null, cause)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ class DefaultNotifiableEventResolver(
|
||||||
): ResolvePushEventsResult {
|
): ResolvePushEventsResult {
|
||||||
Timber.d("Queueing notifications: $notificationEventRequests")
|
Timber.d("Queueing notifications: $notificationEventRequests")
|
||||||
val client = matrixClientProvider.getOrRestore(sessionId).getOrElse {
|
val client = matrixClientProvider.getOrRestore(sessionId).getOrElse {
|
||||||
return Result.failure(IllegalStateException("Couldn't get or restore client for session $sessionId"))
|
return Result.failure(it)
|
||||||
}
|
}
|
||||||
val ids = notificationEventRequests.groupBy { it.roomId }
|
val ids = notificationEventRequests.groupBy { it.roomId }
|
||||||
.mapValues { (_, requests) ->
|
.mapValues { (_, requests) ->
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||||
import io.element.android.libraries.di.annotations.ApplicationContext
|
import io.element.android.libraries.di.annotations.ApplicationContext
|
||||||
|
import io.element.android.libraries.matrix.api.auth.SessionRestorationException
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
import io.element.android.libraries.push.api.push.NotificationEventRequest
|
import io.element.android.libraries.push.api.push.NotificationEventRequest
|
||||||
import io.element.android.libraries.push.api.push.SyncOnNotifiableEvent
|
import io.element.android.libraries.push.api.push.SyncOnNotifiableEvent
|
||||||
|
|
@ -63,9 +64,9 @@ class FetchNotificationsWorker(
|
||||||
return@withContext Result.retry()
|
return@withContext Result.retry()
|
||||||
}
|
}
|
||||||
|
|
||||||
val failedSyncForSessions = mutableSetOf<SessionId>()
|
val failedSyncForSessions = mutableMapOf<SessionId, Throwable>()
|
||||||
|
|
||||||
val groupedRequests = requests.groupBy { it.sessionId }
|
val groupedRequests = requests.groupBy { it.sessionId }.toMutableMap()
|
||||||
for ((sessionId, notificationRequests) in groupedRequests) {
|
for ((sessionId, notificationRequests) in groupedRequests) {
|
||||||
Timber.d("Processing notification requests for session $sessionId")
|
Timber.d("Processing notification requests for session $sessionId")
|
||||||
eventResolver.resolveEvents(sessionId, notificationRequests)
|
eventResolver.resolveEvents(sessionId, notificationRequests)
|
||||||
|
|
@ -75,7 +76,7 @@ class FetchNotificationsWorker(
|
||||||
(queue.results as MutableSharedFlow).emit(requests to result)
|
(queue.results as MutableSharedFlow).emit(requests to result)
|
||||||
},
|
},
|
||||||
onFailure = {
|
onFailure = {
|
||||||
failedSyncForSessions += sessionId
|
failedSyncForSessions[sessionId] = it
|
||||||
Timber.e(it, "Failed to resolve notification events for session $sessionId")
|
Timber.e(it, "Failed to resolve notification events for session $sessionId")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -83,7 +84,13 @@ class FetchNotificationsWorker(
|
||||||
|
|
||||||
// If there were failures for whole sessions, we retry all their requests
|
// If there were failures for whole sessions, we retry all their requests
|
||||||
if (failedSyncForSessions.isNotEmpty()) {
|
if (failedSyncForSessions.isNotEmpty()) {
|
||||||
for (failedSessionId in failedSyncForSessions) {
|
@Suppress("LoopWithTooManyJumpStatements")
|
||||||
|
for ((failedSessionId, exception) in failedSyncForSessions) {
|
||||||
|
if (exception.cause is SessionRestorationException) {
|
||||||
|
Timber.e(exception, "Session $failedSessionId could not be restored, not retrying notification fetching")
|
||||||
|
groupedRequests.remove(failedSessionId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
val requestsToRetry = groupedRequests[failedSessionId] ?: continue
|
val requestsToRetry = groupedRequests[failedSessionId] ?: continue
|
||||||
Timber.d("Re-scheduling ${requestsToRetry.size} failed notification requests for session $failedSessionId")
|
Timber.d("Re-scheduling ${requestsToRetry.size} failed notification requests for session $failedSessionId")
|
||||||
workManagerScheduler.submit(
|
workManagerScheduler.submit(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue