Restore manual Client cleanup on session logout (#4333)
This is done to fix an issue where the Nodes that contain these dependencies are leaked and the `Client` and other SDK-related components can keep working in background for a while, until the caches holding the Nodes are flushed or the app is restarted.
This commit is contained in:
parent
425d53a12b
commit
10557444dd
5 changed files with 41 additions and 6 deletions
|
|
@ -19,6 +19,7 @@ import org.matrix.rustcomponents.sdk.ClientDelegate
|
||||||
import org.matrix.rustcomponents.sdk.ClientSessionDelegate
|
import org.matrix.rustcomponents.sdk.ClientSessionDelegate
|
||||||
import org.matrix.rustcomponents.sdk.Session
|
import org.matrix.rustcomponents.sdk.Session
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -43,13 +44,20 @@ class RustClientSessionDelegate(
|
||||||
private val updateTokensDispatcher = coroutineDispatchers.io.limitedParallelism(1)
|
private val updateTokensDispatcher = coroutineDispatchers.io.limitedParallelism(1)
|
||||||
|
|
||||||
// This Client needs to be set up as soon as possible so `didReceiveAuthError` can work properly.
|
// This Client needs to be set up as soon as possible so `didReceiveAuthError` can work properly.
|
||||||
private var client: RustMatrixClient? = null
|
private var client: WeakReference<RustMatrixClient> = WeakReference(null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the [ClientDelegate] for the [RustMatrixClient], and keeps a reference to the client so it can be used later.
|
* Sets the [ClientDelegate] for the [RustMatrixClient], and keeps a reference to the client so it can be used later.
|
||||||
*/
|
*/
|
||||||
fun bindClient(client: RustMatrixClient) {
|
fun bindClient(client: RustMatrixClient) {
|
||||||
this.client = client
|
this.client = WeakReference(client)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the current client reference.
|
||||||
|
*/
|
||||||
|
fun clearCurrentClient() {
|
||||||
|
this.client.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun saveSessionInKeychain(session: Session) {
|
override fun saveSessionInKeychain(session: Session) {
|
||||||
|
|
@ -81,7 +89,7 @@ class RustClientSessionDelegate(
|
||||||
clientLog.v("didReceiveAuthError -> do the cleanup")
|
clientLog.v("didReceiveAuthError -> do the cleanup")
|
||||||
// TODO handle isSoftLogout parameter.
|
// TODO handle isSoftLogout parameter.
|
||||||
appCoroutineScope.launch(updateTokensDispatcher) {
|
appCoroutineScope.launch(updateTokensDispatcher) {
|
||||||
val currentClient = client
|
val currentClient = client.get()
|
||||||
if (currentClient == null) {
|
if (currentClient == null) {
|
||||||
clientLog.w("didReceiveAuthError -> no client, exiting")
|
clientLog.w("didReceiveAuthError -> no client, exiting")
|
||||||
isLoggingOut.set(false)
|
isLoggingOut.set(false)
|
||||||
|
|
@ -101,7 +109,7 @@ class RustClientSessionDelegate(
|
||||||
} else {
|
} else {
|
||||||
clientLog.d("No session data found.")
|
clientLog.d("No session data found.")
|
||||||
}
|
}
|
||||||
client?.logout(userInitiated = false, ignoreSdkError = true)
|
currentClient.logout(userInitiated = false, ignoreSdkError = true)
|
||||||
}.invokeOnCompletion {
|
}.invokeOnCompletion {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
clientLog.e(it, "Failed to remove session data.")
|
clientLog.e(it, "Failed to remove session data.")
|
||||||
|
|
|
||||||
|
|
@ -482,6 +482,13 @@ class RustMatrixClient(
|
||||||
clientDelegateTaskHandle?.cancelAndDestroy()
|
clientDelegateTaskHandle?.cancelAndDestroy()
|
||||||
notificationSettingsService.destroy()
|
notificationSettingsService.destroy()
|
||||||
verificationService.destroy()
|
verificationService.destroy()
|
||||||
|
|
||||||
|
sessionDelegate.clearCurrentClient()
|
||||||
|
innerRoomListService.destroy()
|
||||||
|
notificationService.destroy()
|
||||||
|
notificationProcessSetup.destroy()
|
||||||
|
encryptionService.destroy()
|
||||||
|
innerClient.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getCacheSize(): Long {
|
override suspend fun getCacheSize(): Long {
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,10 @@ class RustMatrixAuthenticationService @Inject constructor(
|
||||||
)
|
)
|
||||||
newMatrixClientObserver?.invoke(rustMatrixClientFactory.create(client))
|
newMatrixClientObserver?.invoke(rustMatrixClientFactory.create(client))
|
||||||
sessionStore.storeData(sessionData)
|
sessionStore.storeData(sessionData)
|
||||||
|
|
||||||
|
// Clean up the strong reference held here since it's no longer necessary
|
||||||
|
currentClient = null
|
||||||
|
|
||||||
SessionId(sessionData.userId)
|
SessionId(sessionData.userId)
|
||||||
}.mapFailure { failure ->
|
}.mapFailure { failure ->
|
||||||
failure.mapAuthenticationException()
|
failure.mapAuthenticationException()
|
||||||
|
|
@ -229,6 +233,10 @@ class RustMatrixAuthenticationService @Inject constructor(
|
||||||
pendingOidcAuthorizationData = null
|
pendingOidcAuthorizationData = null
|
||||||
newMatrixClientObserver?.invoke(rustMatrixClientFactory.create(client))
|
newMatrixClientObserver?.invoke(rustMatrixClientFactory.create(client))
|
||||||
sessionStore.storeData(sessionData)
|
sessionStore.storeData(sessionData)
|
||||||
|
|
||||||
|
// Clean up the strong reference held here since it's no longer necessary
|
||||||
|
currentClient = null
|
||||||
|
|
||||||
SessionId(sessionData.userId)
|
SessionId(sessionData.userId)
|
||||||
}.mapFailure { failure ->
|
}.mapFailure { failure ->
|
||||||
failure.mapAuthenticationException()
|
failure.mapAuthenticationException()
|
||||||
|
|
@ -264,6 +272,10 @@ class RustMatrixAuthenticationService @Inject constructor(
|
||||||
)
|
)
|
||||||
newMatrixClientObserver?.invoke(rustMatrixClientFactory.create(client))
|
newMatrixClientObserver?.invoke(rustMatrixClientFactory.create(client))
|
||||||
sessionStore.storeData(sessionData)
|
sessionStore.storeData(sessionData)
|
||||||
|
|
||||||
|
// Clean up the strong reference held here since it's no longer necessary
|
||||||
|
currentClient = null
|
||||||
|
|
||||||
SessionId(sessionData.userId)
|
SessionId(sessionData.userId)
|
||||||
}.mapFailure {
|
}.mapFailure {
|
||||||
when (it) {
|
when (it) {
|
||||||
|
|
|
||||||
|
|
@ -186,11 +186,11 @@ internal class RustEncryptionService(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deviceCurve25519(): String? {
|
override suspend fun deviceCurve25519(): String? {
|
||||||
return service.curve25519Key()
|
return runCatching { service.curve25519Key() }.getOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deviceEd25519(): String? {
|
override suspend fun deviceEd25519(): String? {
|
||||||
return service.ed25519Key()
|
return runCatching { service.ed25519Key() }.getOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun startIdentityReset(): Result<IdentityResetHandle?> {
|
override suspend fun startIdentityReset(): Result<IdentityResetHandle?> {
|
||||||
|
|
@ -219,4 +219,8 @@ internal class RustEncryptionService(
|
||||||
// requestFromHomeserverIfNeeded = true,
|
// requestFromHomeserverIfNeeded = true,
|
||||||
) ?: error("User identity not found")
|
) ?: error("User identity not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun destroy() {
|
||||||
|
service.destroy()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,4 +35,8 @@ class RustNotificationService(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun destroy() {
|
||||||
|
notificationClient.destroy()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue