Try mitigating unexpected logouts (#2251)

* Try mitigating unexpected logouts.

Try making getting/storing session data use a Mutex for synchronization.

Also added some more logs so we can understand exactly where it's failing.
This commit is contained in:
Jorge Martin Espinosa 2024-01-18 16:22:25 +01:00 committed by GitHub
parent e00d1abe44
commit 6ecce81f45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 45 additions and 15 deletions

View file

@ -28,6 +28,8 @@ import io.element.android.libraries.sessionstorage.api.SessionData
import io.element.android.libraries.sessionstorage.api.SessionStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import timber.log.Timber
import javax.inject.Inject
@ -37,6 +39,8 @@ class DatabaseSessionStore @Inject constructor(
private val database: SessionDatabase,
private val dispatchers: CoroutineDispatchers,
) : SessionStore {
private val sessionDataMutex = Mutex()
override fun isLoggedIn(): Flow<LoggedInState> {
return database.sessionDataQueries.selectFirst()
.asFlow()
@ -53,11 +57,11 @@ class DatabaseSessionStore @Inject constructor(
}
}
override suspend fun storeData(sessionData: SessionData) {
override suspend fun storeData(sessionData: SessionData) = sessionDataMutex.withLock {
database.sessionDataQueries.insertSessionData(sessionData.toDbModel())
}
override suspend fun updateData(sessionData: SessionData) {
override suspend fun updateData(sessionData: SessionData) = sessionDataMutex.withLock {
val result = database.sessionDataQueries.selectByUserId(sessionData.userId)
.executeAsOneOrNull()
?.toApiModel()
@ -66,8 +70,7 @@ class DatabaseSessionStore @Inject constructor(
Timber.e("User ${sessionData.userId} not found in session database")
return
}
// Copy new data from SDK, but keep login timestamp
// Copy new data from SDK, but keep login timestamp
database.sessionDataQueries.updateSession(
sessionData.copy(
loginTimestamp = result.loginTimestamp,
@ -76,21 +79,27 @@ class DatabaseSessionStore @Inject constructor(
}
override suspend fun getLatestSession(): SessionData? {
return database.sessionDataQueries.selectFirst()
.executeAsOneOrNull()
?.toApiModel()
return sessionDataMutex.withLock {
database.sessionDataQueries.selectFirst()
.executeAsOneOrNull()
?.toApiModel()
}
}
override suspend fun getSession(sessionId: String): SessionData? {
return database.sessionDataQueries.selectByUserId(sessionId)
.executeAsOneOrNull()
?.toApiModel()
return sessionDataMutex.withLock {
database.sessionDataQueries.selectByUserId(sessionId)
.executeAsOneOrNull()
?.toApiModel()
}
}
override suspend fun getAllSessions(): List<SessionData> {
return database.sessionDataQueries.selectAll()
.executeAsList()
.map { it.toApiModel() }
return sessionDataMutex.withLock {
database.sessionDataQueries.selectAll()
.executeAsList()
.map { it.toApiModel() }
}
}
override fun sessionsFlow(): Flow<List<SessionData>> {
@ -102,6 +111,8 @@ class DatabaseSessionStore @Inject constructor(
}
override suspend fun removeSession(sessionId: String) {
database.sessionDataQueries.removeSession(sessionId)
sessionDataMutex.withLock {
database.sessionDataQueries.removeSession(sessionId)
}
}
}