Trying monarchy to manage realm

This commit is contained in:
ganfra 2018-10-18 11:16:02 +02:00
parent 1646687e6d
commit 3f07ed9806
9 changed files with 44 additions and 57 deletions

View File

@ -22,6 +22,7 @@ allprojects {
google()
jcenter()
maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
maven { url 'https://jitpack.io' }
}
}


View File

@ -68,6 +68,9 @@ dependencies {
implementation "com.squareup.moshi:moshi-adapters:$moshi_version"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"

// Database
implementation 'com.github.Zhuinden:realm-monarchy:0.5.1'

// Paging
implementation "android.arch.paging:runtime:1.0.1"


View File

@ -2,13 +2,13 @@ package im.vector.matrix.android.api

import android.arch.lifecycle.ProcessLifecycleOwner
import android.content.Context
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.auth.Authenticator
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.internal.auth.AuthModule
import im.vector.matrix.android.internal.di.MatrixModule
import im.vector.matrix.android.internal.di.NetworkModule
import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
import io.realm.Realm
import org.koin.standalone.KoinComponent
import org.koin.standalone.StandAloneContext.loadKoinModules
import org.koin.standalone.inject
@ -22,7 +22,7 @@ class Matrix(matrixOptions: MatrixOptions) : KoinComponent {
var currentSession: Session? = null

init {
Realm.init(matrixOptions.context)
Monarchy.init(matrixOptions.context)
val matrixModule = MatrixModule(matrixOptions)
val networkModule = NetworkModule()
val authModule = AuthModule()

View File

@ -7,7 +7,6 @@ import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.internal.auth.data.SessionParams
import im.vector.matrix.android.internal.database.SessionRealmHolder
import im.vector.matrix.android.internal.session.room.RoomSummaryObserver
import im.vector.matrix.android.internal.session.sync.SyncModule
import im.vector.matrix.android.internal.session.sync.job.SyncThread
@ -18,8 +17,7 @@ import org.koin.standalone.getKoin
import org.koin.standalone.inject


class DefaultSession(private val sessionParams: SessionParams
) : Session, KoinComponent, RoomService {
class DefaultSession(private val sessionParams: SessionParams) : Session, KoinComponent, RoomService {

companion object {
const val SCOPE: String = "session"
@ -27,7 +25,6 @@ class DefaultSession(private val sessionParams: SessionParams

private lateinit var scope: Scope

private val realmInstanceHolder by inject<SessionRealmHolder>()
private val roomSummaryObserver by inject<RoomSummaryObserver>()
private val roomService by inject<RoomService>()
private val syncThread by inject<SyncThread>()
@ -42,7 +39,6 @@ class DefaultSession(private val sessionParams: SessionParams
val syncModule = SyncModule()
StandAloneContext.loadKoinModules(listOf(sessionModule, syncModule))
scope = getKoin().getOrCreateScope(SCOPE)
realmInstanceHolder.open()
roomSummaryObserver.start()
syncThread.start()
}
@ -54,7 +50,6 @@ class DefaultSession(private val sessionParams: SessionParams
assert(isOpen)
syncThread.kill()
roomSummaryObserver.dispose()
realmInstanceHolder.close()
scope.close()
isOpen = false
}

View File

@ -1,8 +1,8 @@
package im.vector.matrix.android.internal.session

import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.internal.auth.data.SessionParams
import im.vector.matrix.android.internal.database.SessionRealmHolder
import im.vector.matrix.android.internal.legacy.MXDataHandler
import im.vector.matrix.android.internal.legacy.MXSession
import im.vector.matrix.android.internal.legacy.data.store.MXFileStore
@ -23,7 +23,7 @@ class SessionModule(private val sessionParams: SessionParams) : Module {
}

scope(DefaultSession.SCOPE) {
SessionRealmHolder(get())
Monarchy.Builder().setRealmConfiguration(get()).build()
}

scope(DefaultSession.SCOPE) {
@ -34,11 +34,11 @@ class SessionModule(private val sessionParams: SessionParams) : Module {
}

scope(DefaultSession.SCOPE) {
RoomSummaryObserver(get(), get(), get())
RoomSummaryObserver(get())
}

scope(DefaultSession.SCOPE) {
DefaultRoomService(get(), get()) as RoomService
DefaultRoomService(get()) as RoomService
}

scope(DefaultSession.SCOPE) {

View File

@ -1,38 +1,36 @@
package im.vector.matrix.android.internal.session.room

import android.arch.lifecycle.LiveData
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.RoomService
import im.vector.matrix.android.internal.database.RealmLiveData
import im.vector.matrix.android.internal.database.SessionRealmHolder
import im.vector.matrix.android.internal.database.model.RoomEntity
import im.vector.matrix.android.internal.database.query.getAll
import im.vector.matrix.android.internal.database.query.getForId
import io.realm.Realm
import io.realm.RealmConfiguration

class DefaultRoomService(private val realmConfiguration: RealmConfiguration,
val mainThreadRealm: SessionRealmHolder)
: RoomService {
class DefaultRoomService(private val monarchy: Monarchy) : RoomService {

override fun getAllRooms(): List<Room> {
val realm = Realm.getInstance(realmConfiguration)
val rooms = RoomEntity.getAll(realm).findAll().map { DefaultRoom(it.roomId) }
realm.close()
var rooms: List<Room> = emptyList()
monarchy.doWithRealm { realm ->
rooms = RoomEntity.getAll(realm).findAll().map { DefaultRoom(it.roomId) }
}
return rooms
}

override fun getRoom(roomId: String): Room? {
val realm = Realm.getInstance(realmConfiguration)
val room = RoomEntity.getForId(realm, roomId)?.let { DefaultRoom(it.roomId) }
realm.close()
var room: Room? = null
monarchy.doWithRealm { realm ->
room = RoomEntity.getForId(realm, roomId)?.let { DefaultRoom(it.roomId) }
}
return room
}

override fun rooms(): LiveData<List<Room>> {
val roomResults = RoomEntity.getAll(mainThreadRealm.instance).findAllAsync()
return RealmLiveData(roomResults) { DefaultRoom(it.roomId) }
return monarchy.findAllMappedWithChanges(
{ realm -> RoomEntity.getAll(realm) },
{ DefaultRoom(it.roomId) }
)
}


}

View File

@ -1,9 +1,9 @@
package im.vector.matrix.android.internal.session.room

import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.room.model.RoomNameContent
import im.vector.matrix.android.api.session.room.model.RoomTopicContent
import im.vector.matrix.android.internal.database.SessionRealmHolder
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.model.RoomEntity
@ -11,28 +11,22 @@ import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.query.getAll
import im.vector.matrix.android.internal.database.query.getAllFromRoom
import im.vector.matrix.android.internal.database.query.getLast
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.RealmResults
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.util.concurrent.atomic.AtomicBoolean

internal class RoomSummaryObserver(private val mainThreadRealm: SessionRealmHolder,
private val matrixCoroutineDispatchers: MatrixCoroutineDispatchers,
private val realmConfiguration: RealmConfiguration
) {
internal class RoomSummaryObserver(private val monarchy: Monarchy) {

private lateinit var roomResults: RealmResults<RoomEntity>
private var isStarted = AtomicBoolean(false)

fun start() {
if (isStarted.compareAndSet(false, true)) {
roomResults = RoomEntity.getAll(mainThreadRealm.instance).findAllAsync()
roomResults.addChangeListener { rooms, changeSet ->
manageRoomResults(rooms, changeSet.changes)
manageRoomResults(rooms, changeSet.insertions)
monarchy.doWithRealm {
roomResults = RoomEntity.getAll(it).findAllAsync()
roomResults.addChangeListener { rooms, changeSet ->
manageRoomResults(rooms, changeSet.changes)
manageRoomResults(rooms, changeSet.insertions)
}
}
}
}
@ -54,20 +48,18 @@ internal class RoomSummaryObserver(private val mainThreadRealm: SessionRealmHold
}
}

private fun manageRoom(roomId: String) = GlobalScope.launch(matrixCoroutineDispatchers.io) {
val realm = Realm.getInstance(realmConfiguration)
val roomEvents = EventEntity.getAllFromRoom(realm, roomId)
val lastNameEvent = roomEvents.getLast(EventType.STATE_ROOM_NAME)?.asDomain()
val lastTopicEvent = roomEvents.getLast(EventType.STATE_ROOM_TOPIC)?.asDomain()
val lastMessageEvent = roomEvents.getLast(EventType.MESSAGE)
private fun manageRoom(roomId: String) {
monarchy.writeAsync { realm ->
val roomEvents = EventEntity.getAllFromRoom(realm, roomId)
val lastNameEvent = roomEvents.getLast(EventType.STATE_ROOM_NAME)?.asDomain()
val lastTopicEvent = roomEvents.getLast(EventType.STATE_ROOM_TOPIC)?.asDomain()
val lastMessageEvent = roomEvents.getLast(EventType.MESSAGE)

realm.executeTransaction { realmInstance ->
val roomSummary = realmInstance.copyToRealmOrUpdate(RoomSummaryEntity(roomId))
val roomSummary = realm.copyToRealmOrUpdate(RoomSummaryEntity(roomId))
roomSummary.displayName = lastNameEvent?.content<RoomNameContent>()?.name
roomSummary.topic = lastTopicEvent?.content<RoomTopicContent>()?.topic
roomSummary.lastMessage = lastMessageEvent
}
realm.close()
}

}

View File

@ -1,5 +1,6 @@
package im.vector.matrix.android.internal.session.sync

import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.internal.database.mapper.asEntity
import im.vector.matrix.android.internal.database.model.ChunkEntity
@ -10,10 +11,9 @@ import im.vector.matrix.android.internal.database.query.getLastChunkFromRoom
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync
import im.vector.matrix.android.internal.session.sync.model.RoomSync
import io.realm.Realm
import io.realm.RealmConfiguration


class RoomSyncHandler(private val realmConfiguration: RealmConfiguration) {
class RoomSyncHandler(private val monarchy: Monarchy) {

sealed class HandlingStrategy {
data class JOINED(val data: Map<String, RoomSync>) : HandlingStrategy()
@ -22,16 +22,14 @@ class RoomSyncHandler(private val realmConfiguration: RealmConfiguration) {
}

fun handleRoomSync(handlingStrategy: HandlingStrategy) {
val realm = Realm.getInstance(realmConfiguration)
realm.executeTransaction { realmInstance ->
monarchy.writeAsync { realm ->
val roomEntities = when (handlingStrategy) {
is HandlingStrategy.JOINED -> handlingStrategy.data.map { handleJoinedRoom(realm, it.key, it.value) }
is HandlingStrategy.INVITED -> handlingStrategy.data.map { handleInvitedRoom(realm, it.key, it.value) }
is HandlingStrategy.LEFT -> handlingStrategy.data.map { handleLeftRoom(it.key, it.value) }
}
realmInstance.insertOrUpdate(roomEntities)
realm.insertOrUpdate(roomEntities)
}
realm.close()
}