Remove some use of sync write in realm
This commit is contained in:
parent
fb3e953e28
commit
93ef3edab3
|
@ -67,5 +67,5 @@ interface Authenticator {
|
|||
/**
|
||||
* Create a session after a SSO successful login
|
||||
*/
|
||||
fun createSessionFromSso(credentials: Credentials, homeServerConnectionConfig: HomeServerConnectionConfig): Session
|
||||
fun createSessionFromSso(credentials: Credentials, homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback<Session>): Cancelable
|
||||
}
|
||||
|
|
|
@ -112,10 +112,24 @@ internal class DefaultAuthenticator @Inject constructor(@Unauthenticated
|
|||
sessionManager.getOrCreateSession(sessionParams)
|
||||
}
|
||||
|
||||
override fun createSessionFromSso(credentials: Credentials, homeServerConnectionConfig: HomeServerConnectionConfig): Session {
|
||||
override fun createSessionFromSso(credentials: Credentials,
|
||||
homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
callback: MatrixCallback<Session>): Cancelable {
|
||||
val job = GlobalScope.launch(coroutineDispatchers.main) {
|
||||
val sessionOrFailure = runCatching {
|
||||
createSessionFromSso(credentials, homeServerConnectionConfig)
|
||||
}
|
||||
sessionOrFailure.foldToCallback(callback)
|
||||
}
|
||||
return CancelableCoroutine(job)
|
||||
|
||||
}
|
||||
|
||||
private suspend fun createSessionFromSso(credentials: Credentials,
|
||||
homeServerConnectionConfig: HomeServerConnectionConfig): Session = withContext(coroutineDispatchers.computation) {
|
||||
val sessionParams = SessionParams(credentials, homeServerConnectionConfig)
|
||||
sessionParamsStore.save(sessionParams)
|
||||
return sessionManager.getOrCreateSession(sessionParams)
|
||||
sessionManager.getOrCreateSession(sessionParams)
|
||||
}
|
||||
|
||||
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
|
||||
|
|
|
@ -27,9 +27,9 @@ internal interface SessionParamsStore {
|
|||
|
||||
fun getAll(): List<SessionParams>
|
||||
|
||||
fun save(sessionParams: SessionParams): Try<Unit>
|
||||
suspend fun save(sessionParams: SessionParams)
|
||||
|
||||
fun delete(userId: String): Try<Unit>
|
||||
suspend fun delete(userId: String)
|
||||
|
||||
fun deleteAll(): Try<Unit>
|
||||
suspend fun deleteAll()
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
|
||||
package im.vector.matrix.android.internal.auth.db
|
||||
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
||||
import im.vector.matrix.android.internal.auth.SessionParamsStore
|
||||
import im.vector.matrix.android.internal.database.awaitTransaction
|
||||
import im.vector.matrix.android.internal.di.AuthDatabase
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
|
@ -62,41 +62,29 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S
|
|||
return sessionParams
|
||||
}
|
||||
|
||||
override fun save(sessionParams: SessionParams): Try<Unit> {
|
||||
return Try {
|
||||
override suspend fun save(sessionParams: SessionParams) {
|
||||
awaitTransaction(realmConfiguration) {
|
||||
val entity = mapper.map(sessionParams)
|
||||
if (entity != null) {
|
||||
val realm = Realm.getInstance(realmConfiguration)
|
||||
realm.executeTransaction {
|
||||
it.insert(entity)
|
||||
}
|
||||
realm.close()
|
||||
it.insert(entity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun delete(userId: String): Try<Unit> {
|
||||
return Try {
|
||||
val realm = Realm.getInstance(realmConfiguration)
|
||||
realm.executeTransaction {
|
||||
it.where(SessionParamsEntity::class.java)
|
||||
.equalTo(SessionParamsEntityFields.USER_ID, userId)
|
||||
.findAll()
|
||||
.deleteAllFromRealm()
|
||||
}
|
||||
realm.close()
|
||||
override suspend fun delete(userId: String) {
|
||||
awaitTransaction(realmConfiguration) {
|
||||
it.where(SessionParamsEntity::class.java)
|
||||
.equalTo(SessionParamsEntityFields.USER_ID, userId)
|
||||
.findAll()
|
||||
.deleteAllFromRealm()
|
||||
}
|
||||
}
|
||||
|
||||
override fun deleteAll(): Try<Unit> {
|
||||
return Try {
|
||||
val realm = Realm.getInstance(realmConfiguration)
|
||||
realm.executeTransaction {
|
||||
it.where(SessionParamsEntity::class.java)
|
||||
.findAll()
|
||||
.deleteAllFromRealm()
|
||||
}
|
||||
realm.close()
|
||||
override suspend fun deleteAll() {
|
||||
awaitTransaction(realmConfiguration) {
|
||||
it.where(SessionParamsEntity::class.java)
|
||||
.findAll()
|
||||
.deleteAllFromRealm()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package im.vector.matrix.android.internal.database.query
|
||||
|
||||
import im.vector.matrix.android.internal.database.awaitTransaction
|
||||
import im.vector.matrix.android.internal.database.model.FilterEntity
|
||||
import im.vector.matrix.android.internal.session.filter.FilterFactory
|
||||
import io.realm.Realm
|
||||
|
@ -25,18 +26,17 @@ import io.realm.kotlin.where
|
|||
/**
|
||||
* Get the current filter, create one if it does not exist
|
||||
*/
|
||||
internal fun FilterEntity.Companion.getFilter(realm: Realm): FilterEntity {
|
||||
internal suspend fun FilterEntity.Companion.getFilter(realm: Realm): FilterEntity {
|
||||
var filter = realm.where<FilterEntity>().findFirst()
|
||||
if (filter == null) {
|
||||
realm.executeTransaction {
|
||||
realm.createObject<FilterEntity>().apply {
|
||||
filterBodyJson = FilterFactory.createDefaultFilterBody().toJSONString()
|
||||
roomEventFilterJson = FilterFactory.createDefaultRoomFilter().toJSONString()
|
||||
filterId = ""
|
||||
}
|
||||
filter = FilterEntity().apply {
|
||||
filterBodyJson = FilterFactory.createDefaultFilterBody().toJSONString()
|
||||
roomEventFilterJson = FilterFactory.createDefaultRoomFilter().toJSONString()
|
||||
filterId = ""
|
||||
}
|
||||
awaitTransaction(realm.configuration) {
|
||||
it.insert(filter)
|
||||
}
|
||||
filter = realm.where<FilterEntity>().findFirst()!!
|
||||
}
|
||||
|
||||
return filter
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ internal object MatrixModule {
|
|||
@MatrixScope
|
||||
fun providesMatrixCoroutineDispatchers(): MatrixCoroutineDispatchers {
|
||||
return MatrixCoroutineDispatchers(io = Dispatchers.IO,
|
||||
computation = Dispatchers.IO,
|
||||
computation = Dispatchers.Default,
|
||||
main = Dispatchers.Main,
|
||||
crypto = createBackgroundHandler("Crypto_Thread").asCoroutineDispatcher(),
|
||||
sync = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
|
||||
|
|
|
@ -16,54 +16,46 @@
|
|||
|
||||
package im.vector.matrix.android.internal.session.filter
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.internal.database.model.FilterEntity
|
||||
import im.vector.matrix.android.internal.database.model.FilterEntityFields
|
||||
import im.vector.matrix.android.internal.database.query.getFilter
|
||||
import im.vector.matrix.android.internal.di.SessionDatabase
|
||||
import im.vector.matrix.android.internal.util.awaitTransaction
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import io.realm.kotlin.where
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultFilterRepository @Inject constructor(
|
||||
@SessionDatabase private val realmConfiguration: RealmConfiguration
|
||||
) : FilterRepository {
|
||||
internal class DefaultFilterRepository @Inject constructor(private val monarchy: Monarchy) : FilterRepository {
|
||||
|
||||
override fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean {
|
||||
val result: Boolean
|
||||
override suspend fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean {
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
||||
val filter = FilterEntity.getFilter(realm)
|
||||
val result = if (filter.filterBodyJson != filterBody.toJSONString()) {
|
||||
// Filter has changed, store it and reset the filter Id
|
||||
monarchy.awaitTransaction {
|
||||
// We manage only one filter for now
|
||||
val filterBodyJson = filterBody.toJSONString()
|
||||
val roomEventFilterJson = roomEventFilter.toJSONString()
|
||||
|
||||
val realm = Realm.getInstance(realmConfiguration)
|
||||
val filterEntity = FilterEntity.getFilter(it)
|
||||
|
||||
val filter = FilterEntity.getFilter(realm)
|
||||
|
||||
if (filter.filterBodyJson != filterBody.toJSONString()) {
|
||||
// Filter has changed, store it and reset the filter Id
|
||||
realm.executeTransaction {
|
||||
// We manage only one filter for now
|
||||
val filterBodyJson = filterBody.toJSONString()
|
||||
val roomEventFilterJson = roomEventFilter.toJSONString()
|
||||
|
||||
val filterEntity = FilterEntity.getFilter(it)
|
||||
|
||||
filterEntity.filterBodyJson = filterBodyJson
|
||||
filterEntity.roomEventFilterJson = roomEventFilterJson
|
||||
// Reset filterId
|
||||
filterEntity.filterId = ""
|
||||
filterEntity.filterBodyJson = filterBodyJson
|
||||
filterEntity.roomEventFilterJson = roomEventFilterJson
|
||||
// Reset filterId
|
||||
filterEntity.filterId = ""
|
||||
}
|
||||
true
|
||||
} else {
|
||||
filter.filterId.isBlank()
|
||||
}
|
||||
result = true
|
||||
} else {
|
||||
result = filter.filterId.isBlank()
|
||||
result
|
||||
}
|
||||
|
||||
realm.close()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun storeFilterId(filterBody: FilterBody, filterId: String) {
|
||||
val realm = Realm.getInstance(realmConfiguration)
|
||||
|
||||
realm.executeTransaction {
|
||||
override suspend fun storeFilterId(filterBody: FilterBody, filterId: String) {
|
||||
monarchy.awaitTransaction {
|
||||
// We manage only one filter for now
|
||||
val filterBodyJson = filterBody.toJSONString()
|
||||
|
||||
|
@ -73,39 +65,24 @@ internal class DefaultFilterRepository @Inject constructor(
|
|||
?.findFirst()
|
||||
?.filterId = filterId
|
||||
}
|
||||
|
||||
realm.close()
|
||||
}
|
||||
|
||||
override fun getFilter(): String {
|
||||
val result: String
|
||||
|
||||
val realm = Realm.getInstance(realmConfiguration)
|
||||
|
||||
val filter = FilterEntity.getFilter(realm)
|
||||
|
||||
result = if (filter.filterId.isBlank()) {
|
||||
// Use the Json format
|
||||
filter.filterBodyJson
|
||||
} else {
|
||||
// Use FilterId
|
||||
filter.filterId
|
||||
override suspend fun getFilter(): String {
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use {
|
||||
val filter = FilterEntity.getFilter(it)
|
||||
if (filter.filterId.isBlank()) {
|
||||
// Use the Json format
|
||||
filter.filterBodyJson
|
||||
} else {
|
||||
// Use FilterId
|
||||
filter.filterId
|
||||
}
|
||||
}
|
||||
|
||||
realm.close()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getRoomFilter(): String {
|
||||
val realm = Realm.getInstance(realmConfiguration)
|
||||
|
||||
val filter = FilterEntity.getFilter(realm)
|
||||
|
||||
val result = filter.roomEventFilterJson
|
||||
|
||||
realm.close()
|
||||
|
||||
return result
|
||||
override suspend fun getRoomFilter(): String {
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use {
|
||||
FilterEntity.getFilter(it).roomEventFilterJson
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,36 +21,13 @@ import im.vector.matrix.android.internal.task.TaskExecutor
|
|||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultFilterService @Inject constructor(private val filterRepository: FilterRepository,
|
||||
private val saveFilterTask: SaveFilterTask,
|
||||
internal class DefaultFilterService @Inject constructor(private val saveFilterTask: SaveFilterTask,
|
||||
private val taskExecutor: TaskExecutor) : FilterService {
|
||||
|
||||
// TODO Pass a list of support events instead
|
||||
override fun setFilter(filterPreset: FilterService.FilterPreset) {
|
||||
val filterBody = when (filterPreset) {
|
||||
FilterService.FilterPreset.RiotFilter -> {
|
||||
FilterFactory.createRiotFilterBody()
|
||||
}
|
||||
FilterService.FilterPreset.NoFilter -> {
|
||||
FilterFactory.createDefaultFilterBody()
|
||||
}
|
||||
}
|
||||
|
||||
val roomFilter = when (filterPreset) {
|
||||
FilterService.FilterPreset.RiotFilter -> {
|
||||
FilterFactory.createRiotRoomFilter()
|
||||
}
|
||||
FilterService.FilterPreset.NoFilter -> {
|
||||
FilterFactory.createDefaultRoomFilter()
|
||||
}
|
||||
}
|
||||
|
||||
val updated = filterRepository.storeFilter(filterBody, roomFilter)
|
||||
|
||||
if (updated) {
|
||||
saveFilterTask
|
||||
.configureWith(SaveFilterTask.Params(filterBody))
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
saveFilterTask
|
||||
.configureWith(SaveFilterTask.Params(filterPreset))
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,18 +16,19 @@
|
|||
|
||||
package im.vector.matrix.android.internal.session.filter
|
||||
|
||||
import im.vector.matrix.android.api.session.sync.FilterService
|
||||
import im.vector.matrix.android.internal.di.UserId
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Save a filter to the server
|
||||
* Save a filter, in db and if any changes, upload to the server
|
||||
*/
|
||||
internal interface SaveFilterTask : Task<SaveFilterTask.Params, Unit> {
|
||||
|
||||
data class Params(
|
||||
val filter: FilterBody
|
||||
val filterPreset: FilterService.FilterPreset
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -37,10 +38,29 @@ internal class DefaultSaveFilterTask @Inject constructor(@UserId private val use
|
|||
) : SaveFilterTask {
|
||||
|
||||
override suspend fun execute(params: SaveFilterTask.Params) {
|
||||
val filterResponse = executeRequest<FilterResponse> {
|
||||
// TODO auto retry
|
||||
apiCall = filterAPI.uploadFilter(userId, params.filter)
|
||||
val filterBody = when (params.filterPreset) {
|
||||
FilterService.FilterPreset.RiotFilter -> {
|
||||
FilterFactory.createRiotFilterBody()
|
||||
}
|
||||
FilterService.FilterPreset.NoFilter -> {
|
||||
FilterFactory.createDefaultFilterBody()
|
||||
}
|
||||
}
|
||||
val roomFilter = when (params.filterPreset) {
|
||||
FilterService.FilterPreset.RiotFilter -> {
|
||||
FilterFactory.createRiotRoomFilter()
|
||||
}
|
||||
FilterService.FilterPreset.NoFilter -> {
|
||||
FilterFactory.createDefaultRoomFilter()
|
||||
}
|
||||
}
|
||||
val updated = filterRepository.storeFilter(filterBody, roomFilter)
|
||||
if (updated) {
|
||||
val filterResponse = executeRequest<FilterResponse> {
|
||||
// TODO auto retry
|
||||
apiCall = filterAPI.uploadFilter(userId, filterBody)
|
||||
}
|
||||
filterRepository.storeFilterId(filterBody, filterResponse.filterId)
|
||||
}
|
||||
filterRepository.storeFilterId(params.filter, filterResponse.filterId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,20 +21,20 @@ internal interface FilterRepository {
|
|||
/**
|
||||
* Return true if the filterBody has changed, or need to be sent to the server
|
||||
*/
|
||||
fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean
|
||||
suspend fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean
|
||||
|
||||
/**
|
||||
* Set the filterId of this filter
|
||||
*/
|
||||
fun storeFilterId(filterBody: FilterBody, filterId: String)
|
||||
suspend fun storeFilterId(filterBody: FilterBody, filterId: String)
|
||||
|
||||
/**
|
||||
* Return filter json or filter id
|
||||
*/
|
||||
fun getFilter(): String
|
||||
suspend fun getFilter(): String
|
||||
|
||||
/**
|
||||
* Return the room filter
|
||||
*/
|
||||
fun getRoomFilter(): String
|
||||
suspend fun getRoomFilter(): String
|
||||
}
|
||||
|
|
|
@ -16,27 +16,26 @@
|
|||
|
||||
package im.vector.matrix.android.internal.session.sync
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.internal.database.model.SyncEntity
|
||||
import im.vector.matrix.android.internal.di.SessionDatabase
|
||||
import im.vector.matrix.android.internal.util.awaitTransaction
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class SyncTokenStore @Inject constructor(@SessionDatabase private val realmConfiguration: RealmConfiguration) {
|
||||
internal class SyncTokenStore @Inject constructor(private val monarchy: Monarchy) {
|
||||
|
||||
fun getLastToken(): String? {
|
||||
val realm = Realm.getInstance(realmConfiguration)
|
||||
val token = realm.where(SyncEntity::class.java).findFirst()?.nextBatch
|
||||
realm.close()
|
||||
return token
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use {
|
||||
it.where(SyncEntity::class.java).findFirst()?.nextBatch
|
||||
}
|
||||
}
|
||||
|
||||
fun saveToken(token: String?) {
|
||||
val realm = Realm.getInstance(realmConfiguration)
|
||||
realm.executeTransaction {
|
||||
suspend fun saveToken(token: String?) {
|
||||
monarchy.awaitTransaction {
|
||||
val sync = SyncEntity(token)
|
||||
it.insertOrUpdate(sync)
|
||||
}
|
||||
realm.close()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,6 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
|||
private fun onSessionCreated(session: Session) {
|
||||
activeSessionHolder.setActiveSession(session)
|
||||
session.configureAndStart(pushRuleTriggerListener, sessionListener)
|
||||
|
||||
setState {
|
||||
copy(
|
||||
asyncLoginAction = Success(Unit)
|
||||
|
@ -131,9 +130,11 @@ class LoginViewModel @AssistedInject constructor(@Assisted initialState: LoginVi
|
|||
// Should not happen
|
||||
Timber.w("homeServerConnectionConfig is null")
|
||||
} else {
|
||||
val session = authenticator.createSessionFromSso(action.credentials, homeServerConnectionConfigFinal)
|
||||
|
||||
onSessionCreated(session)
|
||||
authenticator.createSessionFromSso(action.credentials, homeServerConnectionConfigFinal, object : MatrixCallback<Session> {
|
||||
override fun onSuccess(data: Session) {
|
||||
onSessionCreated(data)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue