Improve code readability and documentation.

This commit is contained in:
Benoit Marty 2025-11-14 15:10:24 +01:00
parent 828092c87a
commit 2789c8614d
2 changed files with 55 additions and 40 deletions

View file

@ -15,6 +15,7 @@ import io.element.android.libraries.androidutils.throttler.FirstThrottler
import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.extensions.flatMap
import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.libraries.di.annotations.AppCoroutineScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.MatrixClientProvider import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.push.api.PushService import io.element.android.libraries.push.api.PushService
import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret
@ -54,58 +55,72 @@ class DefaultUnifiedPushRemovedGatewayHandler(
private val pushService: PushService, private val pushService: PushService,
private val unifiedPushRemovedGatewayThrottler: UnifiedPushRemovedGatewayThrottler, private val unifiedPushRemovedGatewayThrottler: UnifiedPushRemovedGatewayThrottler,
) : UnifiedPushRemovedGatewayHandler { ) : UnifiedPushRemovedGatewayHandler {
/**
* The application has been informed by the UnifiedPush distributor that the topic has been deleted.
* So this code aim to unregister the pusher from the homeserver, register a new topic on the
* UnifiedPush application then register a new pusher to the homeserver.
* No registration will happen if the topic deletion has already occurred in the last minute.
*/
override suspend fun handle(clientSecret: String): Result<Unit> { override suspend fun handle(clientSecret: String): Result<Unit> {
// Unregister the pusher for the session with this client secret. val sessionId = pushClientSecret.getUserIdFromSecret(clientSecret) ?: return Result.failure<Unit>(
val userId = pushClientSecret.getUserIdFromSecret(clientSecret) ?: return Result.failure<Unit>(
IllegalStateException("Unable to retrieve session") IllegalStateException("Unable to retrieve session")
).also { ).also {
Timber.tag(loggerTag.value).w("Unable to retrieve session") Timber.tag(loggerTag.value).w("Unable to retrieve session")
} }
return matrixClientProvider return matrixClientProvider
.getOrRestore(userId) .getOrRestore(sessionId)
.onFailure { .onFailure {
// Silently ignore this error (do not invoke onServiceUnregistered)
Timber.tag(loggerTag.value).w(it, "Fails to restore client") Timber.tag(loggerTag.value).w(it, "Fails to restore client")
} }
.flatMap { client -> .flatMap { client ->
unregisterUnifiedPushUseCase.unregister( client.rotateRegistration(clientSecret = clientSecret)
matrixClient = client, .onFailure {
Timber.tag(loggerTag.value).w(it, "Issue during pusher unregistration / re registration")
// Let the user know
pushService.onServiceUnregistered(sessionId)
}
}
}
/**
* Unregister the pusher for the session. Then register again if possible.
*/
private suspend fun MatrixClient.rotateRegistration(clientSecret: String): Result<Unit> {
val unregisterResult = unregisterUnifiedPushUseCase.unregister(
matrixClient = this,
clientSecret = clientSecret, clientSecret = clientSecret,
unregisterUnifiedPush = false, unregisterUnifiedPush = false,
) ).onFailure {
.onFailure {
Timber.tag(loggerTag.value).w(it, "Unable to unregister pusher") Timber.tag(loggerTag.value).w(it, "Unable to unregister pusher")
} }
.flatMap { return unregisterResult.flatMap {
val pushProvider = pushService.getCurrentPushProvider(userId) registerAgain()
val distributor = pushProvider?.getCurrentDistributor(userId)
// Attempt to register again
if (pushProvider != null && distributor != null) {
if (unifiedPushRemovedGatewayThrottler.canRegisterAgain()) {
pushService.registerWith(
client,
pushProvider,
distributor,
)
.onFailure {
Timber.tag(loggerTag.value).w(it, "Unable to register with current data")
} }
} else { }
// Let the user know
Timber.tag(loggerTag.value).w("Second removal in less than 1 minute, do not register again") /**
pushService.onServiceUnregistered(userId) * Attempt to register again, if possible i.e. the current configuration is known and the
Result.success(Unit) * deletion of data in the UnifiedPush application has not already occurred in the last minute.
*/
private suspend fun MatrixClient.registerAgain(): Result<Unit> {
return if (unifiedPushRemovedGatewayThrottler.canRegisterAgain()) {
val pushProvider = pushService.getCurrentPushProvider(sessionId)
val distributor = pushProvider?.getCurrentDistributor(sessionId)
if (pushProvider != null && distributor != null) {
pushService.registerWith(
matrixClient = this,
pushProvider = pushProvider,
distributor = distributor,
).onFailure {
Timber.tag(loggerTag.value).w(it, "Unable to register with current data")
} }
} else { } else {
Result.failure(IllegalStateException("Unable to register again")) Result.failure(IllegalStateException("Unable to register again"))
} }
} } else {
.onFailure { Timber.tag(loggerTag.value).w("Second removal in less than 1 minute, do not register again")
// Let the user know Result.failure(IllegalStateException("Too many requests to register again"))
pushService.onServiceUnregistered(userId)
}
}
.onFailure {
Timber.tag(loggerTag.value).w(it, "Issue during pusher unregistration / re registration")
} }
} }
} }

View file

@ -229,7 +229,7 @@ class DefaultUnifiedPushRemovedGatewayHandlerTest {
onServiceUnregisteredResult.assertions().isNeverCalled() onServiceUnregisteredResult.assertions().isNeverCalled()
// Second attempt in less than 1 minute // Second attempt in less than 1 minute
val result2 = sut.handle(A_SECRET) val result2 = sut.handle(A_SECRET)
assertThat(result2.isSuccess).isTrue() assertThat(result2.isFailure).isTrue()
unregisterLambda.assertions().isCalledExactly(2) unregisterLambda.assertions().isCalledExactly(2)
// Registration is not called twice // Registration is not called twice
registerWithLambda.assertions().isCalledOnce() registerWithLambda.assertions().isCalledOnce()