Make RustMatrixClient.close asynchronous (#4513)

* Make `RustMatrixClient.close` asynchronous

This is a safer way to destroy the Rust instances associated to it. Since `MatrixClient` doesn't implement `Closeable` anymore, the method has been renamed to `destroy` to follow the existing naming in the project.
This commit is contained in:
Jorge Martin Espinosa 2025-04-02 11:52:37 +02:00 committed by GitHub
parent 2e191de343
commit d7ca529db1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 20 additions and 25 deletions

View file

@ -42,10 +42,9 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import java.io.Closeable
import java.util.Optional
interface MatrixClient : Closeable {
interface MatrixClient {
val sessionId: SessionId
val deviceId: DeviceId
val userProfile: StateFlow<MatrixUser>

View file

@ -476,16 +476,13 @@ class RustMatrixClient(
override fun roomDirectoryService(): RoomDirectoryService = roomDirectoryService
override fun close() {
internal suspend fun destroy() {
innerNotificationClient.close()
appCoroutineScope.launch {
roomFactory.destroy()
rustSyncService.destroy()
notificationSettingsService.destroy()
// This is sync, but it can destroy the `Client` instance and block stopping the sync service
notificationProcessSetup.destroy()
}
roomFactory.destroy()
rustSyncService.destroy()
notificationSettingsService.destroy()
notificationProcessSetup.destroy()
sessionCoroutineScope.cancel()
clientDelegateTaskHandle?.cancelAndDestroy()
@ -504,7 +501,7 @@ class RustMatrixClient(
override suspend fun clearCache() {
innerClient.clearCaches()
close()
destroy()
}
override suspend fun logout(userInitiated: Boolean, ignoreSdkError: Boolean) {
@ -527,7 +524,7 @@ class RustMatrixClient(
}
}
}
close()
destroy()
deleteSessionDirectory()
if (userInitiated) {
@ -577,7 +574,7 @@ class RustMatrixClient(
throw it
}
}
close()
destroy()
deleteSessionDirectory()
sessionStore.removeSession(sessionId.value)
}.onFailure {

View file

@ -31,7 +31,7 @@ class RustMatrixClientFactoryTest {
val sut = createRustMatrixClientFactory()
val result = sut.create(aSessionData())
assertThat(result.sessionId).isEqualTo(SessionId("@alice:server.org"))
result.close()
result.destroy()
}
}

View file

@ -28,9 +28,10 @@ import java.io.File
class RustMatrixClientTest {
@Test
fun `ensure that sessionId and deviceId can be retrieved from the client`() = runTest {
createRustMatrixClient().use { sut ->
assertThat(sut.sessionId).isEqualTo(A_USER_ID)
assertThat(sut.deviceId).isEqualTo(A_DEVICE_ID)
createRustMatrixClient().run {
assertThat(sessionId).isEqualTo(A_USER_ID)
assertThat(deviceId).isEqualTo(A_DEVICE_ID)
destroy()
}
}
@ -38,16 +39,16 @@ class RustMatrixClientTest {
fun `clear cache invokes the method clearCaches from the client and close it`() = runTest {
val clearCachesResult = lambdaRecorder<Unit> { }
val closeResult = lambdaRecorder<Unit> { }
createRustMatrixClient(
val client = createRustMatrixClient(
client = FakeRustClient(
clearCachesResult = clearCachesResult,
closeResult = closeResult,
)
).use { sut ->
sut.clearCache()
clearCachesResult.assertions().isCalledOnce()
closeResult.assertions().isCalledOnce()
}
)
client.clearCache()
clearCachesResult.assertions().isCalledOnce()
closeResult.assertions().isCalledOnce()
client.destroy()
}
private fun TestScope.createRustMatrixClient(

View file

@ -181,8 +181,6 @@ class FakeMatrixClient(
deactivateAccountResult(password, eraseData)
}
override fun close() = Unit
override suspend fun getUserProfile(): Result<MatrixUser> = simulateLongTask {
val result = getProfileResults[sessionId]?.getOrNull() ?: MatrixUser(sessionId, userDisplayName, userAvatarUrl)
_userProfile.tryEmit(result)