diff --git a/app/src/main/kotlin/io/element/android/x/di/AppModule.kt b/app/src/main/kotlin/io/element/android/x/di/AppModule.kt index 89ab50d32a..a1d0b50522 100644 --- a/app/src/main/kotlin/io/element/android/x/di/AppModule.kt +++ b/app/src/main/kotlin/io/element/android/x/di/AppModule.kt @@ -37,10 +37,8 @@ import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope -import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.plus import java.io.File -import java.util.concurrent.Executors @Module @ContributesTo(AppScope::class) @@ -99,7 +97,6 @@ object AppModule { io = Dispatchers.IO, computation = Dispatchers.Default, main = Dispatchers.Main, - diffUpdateDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher() ) } diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/CoroutineDispatchers.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/CoroutineDispatchers.kt index a3f1586070..918b6cda8a 100644 --- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/CoroutineDispatchers.kt +++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/CoroutineDispatchers.kt @@ -22,5 +22,4 @@ data class CoroutineDispatchers( val io: CoroutineDispatcher, val computation: CoroutineDispatcher, val main: CoroutineDispatcher, - val diffUpdateDispatcher: CoroutineDispatcher, ) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 7a2f7ea6b8..75beba0901 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -54,7 +54,7 @@ import io.element.android.libraries.matrix.impl.verification.RustSessionVerifica import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.services.toolbox.api.systemclock.SystemClock import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first @@ -73,6 +73,7 @@ import org.matrix.rustcomponents.sdk.CreateRoomParameters as RustCreateRoomParam import org.matrix.rustcomponents.sdk.RoomPreset as RustRoomPreset import org.matrix.rustcomponents.sdk.RoomVisibility as RustRoomVisibility +@OptIn(ExperimentalCoroutinesApi::class) class RustMatrixClient constructor( private val client: Client, private val sessionStore: SessionStore, @@ -85,6 +86,7 @@ class RustMatrixClient constructor( override val sessionId: UserId = UserId(client.userId()) private val roomListService = client.roomListServiceWithEncryption() + private val sessionDispatcher = dispatchers.io.limitedParallelism(64) private val sessionCoroutineScope = appCoroutineScope.childScope(dispatchers.main, "Session-${sessionId}") private val verificationService = RustSessionVerificationService() private val syncService = RustSyncService(roomListService, sessionCoroutineScope) @@ -92,6 +94,7 @@ class RustMatrixClient constructor( client = client, dispatchers = dispatchers, ) + private val notificationService = RustNotificationService(client) private val clientDelegate = object : ClientDelegate { @@ -105,7 +108,7 @@ class RustMatrixClient constructor( RustRoomSummaryDataSource( roomListService = roomListService, sessionCoroutineScope = sessionCoroutineScope, - coroutineDispatchers = dispatchers, + dispatcher = sessionDispatcher, ) override val roomSummaryDataSource: RoomSummaryDataSource @@ -150,7 +153,7 @@ class RustMatrixClient constructor( ) } - private suspend fun pairOfRoom(roomId: RoomId): Pair? = withContext(dispatchers.io) { + private suspend fun pairOfRoom(roomId: RoomId): Pair? = withContext(sessionDispatcher) { val cachedRoomListItem = roomListService.roomOrNull(roomId.value) val fullRoom = cachedRoomListItem?.fullRoom() if (cachedRoomListItem == null || fullRoom == null) { @@ -165,19 +168,19 @@ class RustMatrixClient constructor( return roomId?.let { getRoom(it) } } - override suspend fun ignoreUser(userId: UserId): Result = withContext(dispatchers.io) { + override suspend fun ignoreUser(userId: UserId): Result = withContext(sessionDispatcher) { runCatching { client.ignoreUser(userId.value) } } - override suspend fun unignoreUser(userId: UserId): Result = withContext(dispatchers.io) { + override suspend fun unignoreUser(userId: UserId): Result = withContext(sessionDispatcher) { runCatching { client.unignoreUser(userId.value) } } - override suspend fun createRoom(createRoomParams: CreateRoomParameters): Result = withContext(dispatchers.io) { + override suspend fun createRoom(createRoomParams: CreateRoomParameters): Result = withContext(sessionDispatcher) { runCatching { val rustParams = RustCreateRoomParameters( name = createRoomParams.name, @@ -221,14 +224,14 @@ class RustMatrixClient constructor( return createRoom(createRoomParams) } - override suspend fun getProfile(userId: UserId): Result = withContext(Dispatchers.IO) { + override suspend fun getProfile(userId: UserId): Result = withContext(sessionDispatcher) { runCatching { client.getProfile(userId.value).let(UserProfileMapper::map) } } override suspend fun searchUsers(searchTerm: String, limit: Long): Result = - withContext(dispatchers.io) { + withContext(sessionDispatcher) { runCatching { client.searchUsers(searchTerm, limit.toULong()).let(UserSearchResultMapper::map) } @@ -260,7 +263,7 @@ class RustMatrixClient constructor( baseDirectory.deleteSessionDirectory(userID = sessionId.value, deleteCryptoDb = false) } - override suspend fun logout() = withContext(dispatchers.io) { + override suspend fun logout() = withContext(sessionDispatcher) { try { client.logout() } catch (failure: Throwable) { @@ -271,20 +274,20 @@ class RustMatrixClient constructor( sessionStore.removeSession(sessionId.value) } - override suspend fun loadUserDisplayName(): Result = withContext(dispatchers.io) { + override suspend fun loadUserDisplayName(): Result = withContext(sessionDispatcher) { runCatching { client.displayName() } } - override suspend fun loadUserAvatarURLString(): Result = withContext(dispatchers.io) { + override suspend fun loadUserAvatarURLString(): Result = withContext(sessionDispatcher) { runCatching { client.avatarUrl() } } @OptIn(ExperimentalUnsignedTypes::class) - override suspend fun uploadMedia(mimeType: String, data: ByteArray, progressCallback: ProgressCallback?): Result = withContext(dispatchers.io) { + override suspend fun uploadMedia(mimeType: String, data: ByteArray, progressCallback: ProgressCallback?): Result = withContext(sessionDispatcher) { runCatching { client.uploadMedia(mimeType, data.toUByteArray().toList(), progressCallback?.toProgressWatcher()) } @@ -305,7 +308,7 @@ class RustMatrixClient constructor( private suspend fun File.getCacheSize( userID: String, includeCryptoDb: Boolean = false, - ): Long = withContext(dispatchers.io) { + ): Long = withContext(sessionDispatcher) { // Rust sanitises the user ID replacing invalid characters with an _ val sanitisedUserID = userID.replace(":", "_") val sessionDirectory = File(this@getCacheSize, sanitisedUserID) @@ -327,7 +330,7 @@ class RustMatrixClient constructor( private suspend fun File.deleteSessionDirectory( userID: String, deleteCryptoDb: Boolean = false, - ): Boolean = withContext(dispatchers.io) { + ): Boolean = withContext(sessionDispatcher) { // Rust sanitises the user ID replacing invalid characters with an _ val sanitisedUserID = userID.replace(":", "_") val sessionDirectory = File(this@deleteSessionDirectory, sanitisedUserID) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt index 213cab2256..c958810f5e 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/media/RustMediaLoader.kt @@ -20,6 +20,7 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MediaFile import io.element.android.libraries.matrix.api.media.MediaSource +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.withContext import org.matrix.rustcomponents.sdk.Client import org.matrix.rustcomponents.sdk.mediaSourceFromUrl @@ -29,10 +30,12 @@ import org.matrix.rustcomponents.sdk.MediaSource as RustMediaSource class RustMediaLoader( baseCacheDirectory: File, - private val dispatchers: CoroutineDispatchers, + dispatchers: CoroutineDispatchers, private val innerClient: Client, ) : MatrixMediaLoader { + @OptIn(ExperimentalCoroutinesApi::class) + private val mediaDispatcher = dispatchers.io.limitedParallelism(32) private val cacheDirectory = File(baseCacheDirectory, "temp/media").apply { if (!exists()) { mkdirs() @@ -41,7 +44,7 @@ class RustMediaLoader( @OptIn(ExperimentalUnsignedTypes::class) override suspend fun loadMediaContent(source: MediaSource): Result = - withContext(dispatchers.io) { + withContext(mediaDispatcher) { runCatching { source.toRustMediaSource().use { source -> innerClient.getMediaContent(source).toUByteArray().toByteArray() @@ -55,7 +58,7 @@ class RustMediaLoader( width: Long, height: Long ): Result = - withContext(dispatchers.io) { + withContext(mediaDispatcher) { runCatching { source.toRustMediaSource().use { mediaSource -> innerClient.getMediaThumbnail( @@ -68,7 +71,7 @@ class RustMediaLoader( } override suspend fun downloadMediaFile(source: MediaSource, mimeType: String?, body: String?): Result = - withContext(dispatchers.io) { + withContext(mediaDispatcher) { runCatching { source.toRustMediaSource().use { mediaSource -> val mediaFile = innerClient.getMediaFile( diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index 378e9ae372..11d75641c5 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -23,7 +23,6 @@ import io.element.android.libraries.matrix.api.core.ProgressCallback import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.media.AudioInfo import io.element.android.libraries.matrix.api.media.FileInfo import io.element.android.libraries.matrix.api.media.ImageInfo @@ -32,17 +31,19 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.timeline.MatrixTimeline import io.element.android.libraries.matrix.api.timeline.item.event.EventType import io.element.android.libraries.matrix.impl.core.toProgressWatcher -import io.element.android.libraries.matrix.impl.room.location.toInner import io.element.android.libraries.matrix.impl.media.map +import io.element.android.libraries.matrix.impl.room.location.toInner import io.element.android.libraries.matrix.impl.timeline.RustMatrixTimeline import io.element.android.libraries.matrix.impl.timeline.backPaginationStatusFlow import io.element.android.libraries.matrix.impl.timeline.timelineDiffFlow import io.element.android.services.toolbox.api.systemclock.SystemClock import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -62,6 +63,7 @@ import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown import timber.log.Timber import java.io.File +@OptIn(ExperimentalCoroutinesApi::class) class RustMatrixRoom( override val sessionId: SessionId, private val roomListItem: RoomListItem, @@ -74,6 +76,11 @@ class RustMatrixRoom( override val roomId = RoomId(innerRoom.id()) + // Create a dispatcher for all room methods... + private val roomDispatcher = coroutineDispatchers.io.limitedParallelism(32) + //...except getMember methods as it could quickly fill the roomDispatcher... + private val roomMembersDispatcher = coroutineDispatchers.io.limitedParallelism(8) + private val roomCoroutineScope = sessionCoroutineScope.childScope(coroutineDispatchers.main, "RoomScope-$roomId") private val _membersStateFlow = MutableStateFlow(MatrixRoomMembersState.Unknown) private val isInit = MutableStateFlow(false) @@ -83,7 +90,7 @@ class RustMatrixRoom( matrixRoom = this, innerRoom = innerRoom, roomCoroutineScope = roomCoroutineScope, - coroutineDispatchers = coroutineDispatchers + dispatcher = roomDispatcher ) } @@ -105,7 +112,7 @@ class RustMatrixRoom( timelineLimit = null ) roomListItem.subscribe(settings) - roomCoroutineScope.launch(coroutineDispatchers.computation) { + roomCoroutineScope.launch(roomDispatcher) { innerRoom.timelineDiffFlow { initialList -> _timeline.postItems(initialList) }.onEach { @@ -175,7 +182,7 @@ class RustMatrixRoom( override val activeMemberCount: Long get() = innerRoom.activeMembersCount().toLong() - override suspend fun updateMembers(): Result = withContext(coroutineDispatchers.io) { + override suspend fun updateMembers(): Result = withContext(roomMembersDispatcher) { val currentState = _membersStateFlow.value val currentMembers = currentState.roomMembers() _membersStateFlow.value = MatrixRoomMembersState.Pending(prevRoomMembers = currentMembers) @@ -189,20 +196,20 @@ class RustMatrixRoom( } override suspend fun userDisplayName(userId: UserId): Result = - withContext(coroutineDispatchers.io) { + withContext(roomDispatcher) { runCatching { innerRoom.memberDisplayName(userId.value) } } override suspend fun userAvatarUrl(userId: UserId): Result = - withContext(coroutineDispatchers.io) { + withContext(roomDispatcher) { runCatching { innerRoom.memberAvatarUrl(userId.value) } } - override suspend fun sendMessage(message: String): Result = withContext(coroutineDispatchers.io) { + override suspend fun sendMessage(message: String): Result = withContext(roomDispatcher) { val transactionId = genTransactionId() messageEventContentFromMarkdown(message).use { content -> runCatching { @@ -211,7 +218,7 @@ class RustMatrixRoom( } } - override suspend fun editMessage(originalEventId: EventId?, transactionId: String?, message: String): Result = withContext(coroutineDispatchers.io) { + override suspend fun editMessage(originalEventId: EventId?, transactionId: String?, message: String): Result = withContext(roomDispatcher) { if (originalEventId != null) { runCatching { innerRoom.edit(/* TODO use content */ message, originalEventId.value, transactionId) @@ -224,7 +231,7 @@ class RustMatrixRoom( } } - override suspend fun replyMessage(eventId: EventId, message: String): Result = withContext(coroutineDispatchers.io) { + override suspend fun replyMessage(eventId: EventId, message: String): Result = withContext(roomDispatcher) { val transactionId = genTransactionId() // val content = messageEventContentFromMarkdown(message) runCatching { @@ -232,50 +239,50 @@ class RustMatrixRoom( } } - override suspend fun redactEvent(eventId: EventId, reason: String?) = withContext(coroutineDispatchers.io) { + override suspend fun redactEvent(eventId: EventId, reason: String?) = withContext(roomDispatcher) { val transactionId = genTransactionId() runCatching { innerRoom.redact(eventId.value, reason, transactionId) } } - override suspend fun leave(): Result = withContext(coroutineDispatchers.io) { + override suspend fun leave(): Result = withContext(roomDispatcher) { runCatching { innerRoom.leave() } } - override suspend fun acceptInvitation(): Result = withContext(coroutineDispatchers.io) { + override suspend fun acceptInvitation(): Result = withContext(roomDispatcher) { runCatching { innerRoom.acceptInvitation() } } - override suspend fun rejectInvitation(): Result = withContext(coroutineDispatchers.io) { + override suspend fun rejectInvitation(): Result = withContext(roomDispatcher) { runCatching { innerRoom.rejectInvitation() } } - override suspend fun inviteUserById(id: UserId): Result = withContext(coroutineDispatchers.io) { + override suspend fun inviteUserById(id: UserId): Result = withContext(roomDispatcher) { runCatching { innerRoom.inviteUserById(id.value) } } - override suspend fun canInvite(): Result = withContext(coroutineDispatchers.io) { + override suspend fun canInvite(): Result = withContext(roomMembersDispatcher) { runCatching { innerRoom.member(sessionId.value).use(RoomMember::canInvite) } } - override suspend fun canSendStateEvent(type: StateEventType): Result = withContext(coroutineDispatchers.io) { + override suspend fun canSendStateEvent(type: StateEventType): Result = withContext(roomMembersDispatcher) { runCatching { innerRoom.member(sessionId.value).use { it.canSendState(type.map()) } } } - override suspend fun canSendEvent(type: MessageEventType): Result = withContext(coroutineDispatchers.io) { + override suspend fun canSendEvent(type: MessageEventType): Result = withContext(roomMembersDispatcher) { runCatching { innerRoom.member(sessionId.value).use { it.canSendMessage(type.map()) } } @@ -305,13 +312,13 @@ class RustMatrixRoom( } } - override suspend fun toggleReaction(emoji: String, eventId: EventId): Result = withContext(coroutineDispatchers.io) { + override suspend fun toggleReaction(emoji: String, eventId: EventId): Result = withContext(roomDispatcher) { runCatching { innerRoom.toggleReaction(key = emoji, eventId = eventId.value) } } - override suspend fun forwardEvent(eventId: EventId, roomIds: List): Result = withContext(coroutineDispatchers.io) { + override suspend fun forwardEvent(eventId: EventId, roomIds: List): Result = withContext(roomDispatcher) { runCatching { roomContentForwarder.forward(fromRoom = innerRoom, eventId = eventId, toRoomIds = roomIds) }.onFailure { @@ -320,14 +327,14 @@ class RustMatrixRoom( } override suspend fun retrySendMessage(transactionId: String): Result = - withContext(coroutineDispatchers.io) { + withContext(roomDispatcher) { runCatching { innerRoom.retrySend(transactionId) } } override suspend fun cancelSend(transactionId: String): Result = - withContext(coroutineDispatchers.io) { + withContext(roomDispatcher) { runCatching { innerRoom.cancelSend(transactionId) } @@ -335,40 +342,40 @@ class RustMatrixRoom( @OptIn(ExperimentalUnsignedTypes::class) override suspend fun updateAvatar(mimeType: String, data: ByteArray): Result = - withContext(coroutineDispatchers.io) { + withContext(roomDispatcher) { runCatching { innerRoom.uploadAvatar(mimeType, data.toUByteArray().toList()) } } override suspend fun removeAvatar(): Result = - withContext(coroutineDispatchers.io) { + withContext(roomDispatcher) { runCatching { innerRoom.removeAvatar() } } override suspend fun setName(name: String): Result = - withContext(coroutineDispatchers.io) { + withContext(roomDispatcher) { runCatching { innerRoom.setName(name) } } override suspend fun setTopic(topic: String): Result = - withContext(coroutineDispatchers.io) { + withContext(roomDispatcher) { runCatching { innerRoom.setTopic(topic) } } - private suspend fun fetchMembers() = withContext(coroutineDispatchers.io) { + private suspend fun fetchMembers() = withContext(roomDispatcher) { runCatching { innerRoom.fetchMembers() } } - override suspend fun reportContent(eventId: EventId, reason: String, blockUserId: UserId?): Result = withContext(coroutineDispatchers.io) { + override suspend fun reportContent(eventId: EventId, reason: String, blockUserId: UserId?): Result = withContext(roomDispatcher) { runCatching { innerRoom.reportContent(eventId = eventId.value, score = null, reason = reason) if (blockUserId != null) { @@ -383,7 +390,7 @@ class RustMatrixRoom( description: String?, zoomLevel: Int?, assetType: AssetType?, - ): Result = withContext(coroutineDispatchers.io) { + ): Result = withContext(roomDispatcher) { runCatching { innerRoom.sendLocation( body = body, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt index 3da4c560e8..efdbcf34ad 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt @@ -16,9 +16,9 @@ package io.element.android.libraries.matrix.impl.room -import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.matrix.api.room.RoomSummary import io.element.android.libraries.matrix.api.room.RoomSummaryDataSource +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -41,7 +41,7 @@ import timber.log.Timber internal class RustRoomSummaryDataSource( private val roomListService: RoomListService, private val sessionCoroutineScope: CoroutineScope, - coroutineDispatchers: CoroutineDispatchers, + dispatcher: CoroutineDispatcher, roomSummaryDetailsFactory: RoomSummaryDetailsFactory = RoomSummaryDetailsFactory(), ) : RoomSummaryDataSource { @@ -53,7 +53,7 @@ internal class RustRoomSummaryDataSource( private val inviteRoomsListProcessor = RoomSummaryListProcessor(inviteRooms, roomListService, roomSummaryDetailsFactory, shouldFetchFullRoom = true) init { - sessionCoroutineScope.launch(coroutineDispatchers.computation) { + sessionCoroutineScope.launch(dispatcher) { val allRooms = roomListService.allRooms() allRooms .observeEntriesWithProcessor(allRoomsListProcessor) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt index c7335ba10b..2c3a579b2f 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt @@ -16,7 +16,6 @@ package io.element.android.libraries.matrix.impl.timeline -import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.timeline.MatrixTimeline @@ -25,6 +24,7 @@ import io.element.android.libraries.matrix.impl.timeline.item.event.EventMessage import io.element.android.libraries.matrix.impl.timeline.item.event.EventTimelineItemMapper import io.element.android.libraries.matrix.impl.timeline.item.event.TimelineEventContentMapper import io.element.android.libraries.matrix.impl.timeline.item.virtual.VirtualTimelineItemMapper +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.Flow @@ -45,7 +45,7 @@ class RustMatrixTimeline( roomCoroutineScope: CoroutineScope, private val matrixRoom: MatrixRoom, private val innerRoom: Room, - private val coroutineDispatchers: CoroutineDispatchers, + private val dispatcher: CoroutineDispatcher, ) : MatrixTimeline { private val _timelineItems: MutableStateFlow> = @@ -109,13 +109,13 @@ class RustMatrixTimeline( } } - override suspend fun fetchDetailsForEvent(eventId: EventId): Result = withContext(coroutineDispatchers.io) { + override suspend fun fetchDetailsForEvent(eventId: EventId): Result = withContext(dispatcher) { runCatching { innerRoom.fetchDetailsForEvent(eventId.value) } } - override suspend fun paginateBackwards(requestSize: Int, untilNumberOfItems: Int): Result = withContext(coroutineDispatchers.io) { + override suspend fun paginateBackwards(requestSize: Int, untilNumberOfItems: Int): Result = withContext(dispatcher) { runCatching { Timber.v("Start back paginating for room ${matrixRoom.roomId} ") val paginationOptions = PaginationOptions.UntilNumItems( @@ -131,7 +131,7 @@ class RustMatrixTimeline( } } - override suspend fun sendReadReceipt(eventId: EventId) = withContext(coroutineDispatchers.io) { + override suspend fun sendReadReceipt(eventId: EventId) = withContext(dispatcher) { runCatching { innerRoom.sendReadReceipt(eventId = eventId.value) } diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/Singleton.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/Singleton.kt index 006ca8d9e4..5f8c6555a5 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/Singleton.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/Singleton.kt @@ -22,10 +22,8 @@ import io.element.android.libraries.matrix.api.tracing.TracingConfigurations import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope -import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.plus import timber.log.Timber -import java.util.concurrent.Executors object Singleton { @@ -39,6 +37,5 @@ object Singleton { io = Dispatchers.IO, computation = Dispatchers.Default, main = Dispatchers.Main, - diffUpdateDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher(), ) } diff --git a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/TestCoroutineDispatchers.kt b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/TestCoroutineDispatchers.kt index b8376ddf6f..1fdb5879fc 100644 --- a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/TestCoroutineDispatchers.kt +++ b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/TestCoroutineDispatchers.kt @@ -37,12 +37,10 @@ fun TestScope.testCoroutineDispatchers( io = UnconfinedTestDispatcher(testScheduler), computation = UnconfinedTestDispatcher(testScheduler), main = UnconfinedTestDispatcher(testScheduler), - diffUpdateDispatcher = UnconfinedTestDispatcher(testScheduler), ) false -> CoroutineDispatchers( io = StandardTestDispatcher(testScheduler), computation = StandardTestDispatcher(testScheduler), main = StandardTestDispatcher(testScheduler), - diffUpdateDispatcher = StandardTestDispatcher(testScheduler), ) }