Use an AtomicBoolean instead of a MutableStateFlow to atomically init the RustMatrixRoom. Should improve #951.

This commit is contained in:
Benoit Marty 2023-07-24 18:04:21 +02:00
parent 138bf142a9
commit 0ef49ca6ca

View file

@ -65,6 +65,7 @@ import org.matrix.rustcomponents.sdk.genTransactionId
import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import java.util.concurrent.atomic.AtomicBoolean
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
class RustMatrixRoom( class RustMatrixRoom(
@ -88,7 +89,7 @@ class RustMatrixRoom(
private val roomCoroutineScope = sessionCoroutineScope.childScope(coroutineDispatchers.main, "RoomScope-$roomId") private val roomCoroutineScope = sessionCoroutineScope.childScope(coroutineDispatchers.main, "RoomScope-$roomId")
private val _membersStateFlow = MutableStateFlow<MatrixRoomMembersState>(MatrixRoomMembersState.Unknown) private val _membersStateFlow = MutableStateFlow<MatrixRoomMembersState>(MatrixRoomMembersState.Unknown)
private val isInit = MutableStateFlow(false) private val isInit = AtomicBoolean(false)
private val _syncUpdateFlow = MutableStateFlow(0L) private val _syncUpdateFlow = MutableStateFlow(0L)
private val _timeline by lazy { private val _timeline by lazy {
RustMatrixTimeline( RustMatrixTimeline(
@ -107,41 +108,42 @@ class RustMatrixRoom(
override val timeline: MatrixTimeline = _timeline override val timeline: MatrixTimeline = _timeline
override fun open(): Result<Unit> { override fun open(): Result<Unit> {
if (isInit.value) return Result.failure(IllegalStateException("Listener already registered")) return if (isInit.getAndSet(true)) {
val settings = RoomSubscription( Result.failure(IllegalStateException("Listener already registered"))
requiredState = listOf( } else {
RequiredState(key = EventType.STATE_ROOM_CANONICAL_ALIAS, value = ""), val settings = RoomSubscription(
RequiredState(key = EventType.STATE_ROOM_TOPIC, value = ""), requiredState = listOf(
RequiredState(key = EventType.STATE_ROOM_JOIN_RULES, value = ""), RequiredState(key = EventType.STATE_ROOM_CANONICAL_ALIAS, value = ""),
RequiredState(key = EventType.STATE_ROOM_POWER_LEVELS, value = ""), RequiredState(key = EventType.STATE_ROOM_TOPIC, value = ""),
), RequiredState(key = EventType.STATE_ROOM_JOIN_RULES, value = ""),
timelineLimit = null RequiredState(key = EventType.STATE_ROOM_POWER_LEVELS, value = ""),
) ),
roomListItem.subscribe(settings) timelineLimit = null
roomCoroutineScope.launch(roomDispatcher) { )
innerRoom.timelineDiffFlow { initialList -> roomListItem.subscribe(settings)
_timeline.postItems(initialList) roomCoroutineScope.launch(roomDispatcher) {
}.onEach { diff -> innerRoom.timelineDiffFlow { initialList ->
if (diff.eventOrigin() == EventItemOrigin.SYNC) { _timeline.postItems(initialList)
_syncUpdateFlow.value = systemClock.epochMillis() }.onEach { diff ->
} if (diff.eventOrigin() == EventItemOrigin.SYNC) {
_timeline.postDiff(diff) _syncUpdateFlow.value = systemClock.epochMillis()
}.launchIn(this) }
_timeline.postDiff(diff)
innerRoom.backPaginationStatusFlow()
.onEach {
_timeline.postPaginationStatus(it)
}.launchIn(this) }.launchIn(this)
fetchMembers() innerRoom.backPaginationStatusFlow()
.onEach {
_timeline.postPaginationStatus(it)
}.launchIn(this)
fetchMembers()
}
Result.success(Unit)
} }
isInit.value = true
return Result.success(Unit)
} }
override fun close() { override fun close() {
if (isInit.value) { if (isInit.getAndSet(false)) {
isInit.value = false
roomCoroutineScope.cancel() roomCoroutineScope.cancel()
roomListItem.unsubscribe() roomListItem.unsubscribe()
innerRoom.destroy() innerRoom.destroy()