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.log.logger.LoggerTag
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.push.api.PushService
import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret
@@ -54,58 +55,72 @@ class DefaultUnifiedPushRemovedGatewayHandler(
private val pushService: PushService,
private val unifiedPushRemovedGatewayThrottler: UnifiedPushRemovedGatewayThrottler,
) : 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> {
// Unregister the pusher for the session with this client secret.
val userId = pushClientSecret.getUserIdFromSecret(clientSecret) ?: return Result.failure<Unit>(
val sessionId = pushClientSecret.getUserIdFromSecret(clientSecret) ?: return Result.failure<Unit>(
IllegalStateException("Unable to retrieve session")
).also {
Timber.tag(loggerTag.value).w("Unable to retrieve session")
}
return matrixClientProvider
.getOrRestore(userId)
.getOrRestore(sessionId)
.onFailure {
// Silently ignore this error (do not invoke onServiceUnregistered)
Timber.tag(loggerTag.value).w(it, "Fails to restore client")
}
.flatMap { client ->
unregisterUnifiedPushUseCase.unregister(
matrixClient = client,
client.rotateRegistration(clientSecret = clientSecret)
.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,
unregisterUnifiedPush = false,
)
.onFailure {
).onFailure {
Timber.tag(loggerTag.value).w(it, "Unable to unregister pusher")
}
.flatMap {
val pushProvider = pushService.getCurrentPushProvider(userId)
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")
return unregisterResult.flatMap {
registerAgain()
}
} else {
// Let the user know
Timber.tag(loggerTag.value).w("Second removal in less than 1 minute, do not register again")
pushService.onServiceUnregistered(userId)
Result.success(Unit)
}
/**
* Attempt to register again, if possible i.e. the current configuration is known and the
* 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 {
Result.failure(IllegalStateException("Unable to register again"))
}
}
.onFailure {
// Let the user know
pushService.onServiceUnregistered(userId)
}
}
.onFailure {
Timber.tag(loggerTag.value).w(it, "Issue during pusher unregistration / re registration")
} else {
Timber.tag(loggerTag.value).w("Second removal in less than 1 minute, do not register again")
Result.failure(IllegalStateException("Too many requests to register again"))
}
}
}

View File

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