Skip to content

Commit 9e989b5

Browse files
authored
Merge pull request #1386 from vector-im/feature/fga/replace_async_uniffi_to_blocking
Remove usage of async-uniffi
2 parents e0d3209 + 4883b63 commit 9e989b5

File tree

9 files changed

+75
-51
lines changed

9 files changed

+75
-51
lines changed

changelog.d/1381.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove usage of async-uniffi as it leads to a deadlocks and memory leaks.

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ class RustMatrixClient constructor(
9797
private val innerRoomListService = syncService.roomListService()
9898
private val sessionDispatcher = dispatchers.io.limitedParallelism(64)
9999
private val sessionCoroutineScope = appCoroutineScope.childScope(dispatchers.main, "Session-${sessionId}")
100-
private val rustSyncService = RustSyncService(syncService, sessionCoroutineScope)
101-
private val verificationService = RustSessionVerificationService(rustSyncService)
100+
private val rustSyncService = RustSyncService(syncService, dispatchers, sessionCoroutineScope)
101+
private val verificationService = RustSessionVerificationService(rustSyncService, dispatchers)
102102
private val pushersService = RustPushersService(
103103
client = client,
104104
dispatchers = dispatchers,

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ class RustMatrixClientFactory @Inject constructor(
5353

5454
client.restoreSession(sessionData.toSession())
5555

56-
val syncService = client.syncService()
57-
.finish()
56+
val syncService = client.syncService().finishBlocking()
5857

5958
RustMatrixClient(
6059
client = client,

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsService.kt

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,67 +47,71 @@ class RustNotificationSettingsService(
4747
notificationSettings.setDelegate(notificationSettingsDelegate)
4848
}
4949

50-
override suspend fun getRoomNotificationSettings(roomId: RoomId, isEncrypted: Boolean, isOneToOne: Boolean): Result<RoomNotificationSettings> =
50+
override suspend fun getRoomNotificationSettings(roomId: RoomId, isEncrypted: Boolean, isOneToOne: Boolean): Result<RoomNotificationSettings> = withContext(
51+
dispatchers.io
52+
) {
5153
runCatching {
52-
notificationSettings.getRoomNotificationSettings(roomId.value, isEncrypted, isOneToOne).let(RoomNotificationSettingsMapper::map)
54+
notificationSettings.getRoomNotificationSettingsBlocking(roomId.value, isEncrypted, isOneToOne).let(RoomNotificationSettingsMapper::map)
5355
}
56+
}
5457

55-
override suspend fun getDefaultRoomNotificationMode(isEncrypted: Boolean, isOneToOne: Boolean): Result<RoomNotificationMode> =
58+
override suspend fun getDefaultRoomNotificationMode(isEncrypted: Boolean, isOneToOne: Boolean): Result<RoomNotificationMode> = withContext(dispatchers.io) {
5659
runCatching {
57-
notificationSettings.getDefaultRoomNotificationMode(isEncrypted, isOneToOne).let(RoomNotificationSettingsMapper::mapMode)
60+
notificationSettings.getDefaultRoomNotificationModeBlocking(isEncrypted, isOneToOne).let(RoomNotificationSettingsMapper::mapMode)
5861
}
62+
}
5963

6064
override suspend fun setDefaultRoomNotificationMode(
6165
isEncrypted: Boolean,
6266
mode: RoomNotificationMode,
6367
isOneToOne: Boolean
6468
): Result<Unit> = withContext(dispatchers.io) {
6569
runCatching {
66-
notificationSettings.setDefaultRoomNotificationMode(isEncrypted, isOneToOne, mode.let(RoomNotificationSettingsMapper::mapMode))
70+
notificationSettings.setDefaultRoomNotificationModeBlocking(isEncrypted, isOneToOne, mode.let(RoomNotificationSettingsMapper::mapMode))
6771
}
6872
}
6973

7074
override suspend fun setRoomNotificationMode(roomId: RoomId, mode: RoomNotificationMode): Result<Unit> = withContext(dispatchers.io) {
7175
runCatching {
72-
notificationSettings.setRoomNotificationMode(roomId.value, mode.let(RoomNotificationSettingsMapper::mapMode))
76+
notificationSettings.setRoomNotificationModeBlocking(roomId.value, mode.let(RoomNotificationSettingsMapper::mapMode))
7377
}
7478
}
7579

7680
override suspend fun restoreDefaultRoomNotificationMode(roomId: RoomId): Result<Unit> = withContext(dispatchers.io) {
7781
runCatching {
78-
notificationSettings.restoreDefaultRoomNotificationMode(roomId.value)
82+
notificationSettings.restoreDefaultRoomNotificationModeBlocking(roomId.value)
7983
}
8084
}
8185

8286
override suspend fun muteRoom(roomId: RoomId): Result<Unit> = setRoomNotificationMode(roomId, RoomNotificationMode.MUTE)
8387

8488
override suspend fun unmuteRoom(roomId: RoomId, isEncrypted: Boolean, isOneToOne: Boolean) = withContext(dispatchers.io) {
8589
runCatching {
86-
notificationSettings.unmuteRoom(roomId.value, isEncrypted, isOneToOne)
90+
notificationSettings.unmuteRoomBlocking(roomId.value, isEncrypted, isOneToOne)
8791
}
8892
}
8993

9094
override suspend fun isRoomMentionEnabled(): Result<Boolean> = withContext(dispatchers.io) {
9195
runCatching {
92-
notificationSettings.isRoomMentionEnabled()
96+
notificationSettings.isRoomMentionEnabledBlocking()
9397
}
9498
}
9599

96100
override suspend fun setRoomMentionEnabled(enabled: Boolean): Result<Unit> = withContext(dispatchers.io) {
97101
runCatching {
98-
notificationSettings.setRoomMentionEnabled(enabled)
102+
notificationSettings.setRoomMentionEnabledBlocking(enabled)
99103
}
100104
}
101105

102106
override suspend fun isCallEnabled(): Result<Boolean> = withContext(dispatchers.io) {
103107
runCatching {
104-
notificationSettings.isCallEnabled()
108+
notificationSettings.isCallEnabledBlocking()
105109
}
106110
}
107111

108112
override suspend fun setCallEnabled(enabled: Boolean): Result<Unit> = withContext(dispatchers.io) {
109113
runCatching {
110-
notificationSettings.setCallEnabled(enabled)
114+
notificationSettings.setCallEnabledBlocking(enabled)
111115
}
112116
}
113117
}

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ import kotlinx.coroutines.CancellationException
5555
import kotlinx.coroutines.CoroutineScope
5656
import kotlinx.coroutines.ExperimentalCoroutinesApi
5757
import kotlinx.coroutines.cancel
58+
import kotlinx.coroutines.ensureActive
5859
import kotlinx.coroutines.flow.MutableStateFlow
5960
import kotlinx.coroutines.flow.StateFlow
6061
import kotlinx.coroutines.flow.asStateFlow
6162
import kotlinx.coroutines.withContext
62-
import kotlinx.coroutines.yield
6363
import org.matrix.rustcomponents.sdk.RequiredState
6464
import org.matrix.rustcomponents.sdk.Room
6565
import org.matrix.rustcomponents.sdk.RoomListItem
@@ -188,12 +188,12 @@ class RustMatrixRoom(
188188
_membersStateFlow.value = MatrixRoomMembersState.Pending(prevRoomMembers = currentMembers)
189189
var rustMembers: List<RoomMember>? = null
190190
try {
191-
rustMembers = innerRoom.members().use { membersIterator ->
191+
rustMembers = innerRoom.membersBlocking().use { membersIterator ->
192192
buildList {
193193
while (true) {
194194
// Loading the whole membersIterator as a stop-gap measure.
195195
// We should probably implement some sort of paging in the future.
196-
yield()
196+
ensureActive()
197197
addAll(membersIterator.nextChunk(1000u) ?: break)
198198
}
199199
}
@@ -294,27 +294,27 @@ class RustMatrixRoom(
294294
}
295295
}
296296

297-
override suspend fun canUserInvite(userId: UserId): Result<Boolean> {
298-
return runCatching {
299-
innerRoom.canUserInvite(userId.value)
297+
override suspend fun canUserInvite(userId: UserId): Result<Boolean> = withContext(roomMembersDispatcher) {
298+
runCatching {
299+
innerRoom.canUserInviteBlocking(userId.value)
300300
}
301301
}
302302

303-
override suspend fun canUserRedact(userId: UserId): Result<Boolean> {
304-
return runCatching {
305-
innerRoom.canUserRedact(userId.value)
303+
override suspend fun canUserRedact(userId: UserId): Result<Boolean> = withContext(roomMembersDispatcher) {
304+
runCatching {
305+
innerRoom.canUserRedactBlocking(userId.value)
306306
}
307307
}
308308

309-
override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result<Boolean> {
310-
return runCatching {
311-
innerRoom.canUserSendState(userId.value, type.map())
309+
override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result<Boolean> = withContext(roomMembersDispatcher) {
310+
runCatching {
311+
innerRoom.canUserSendStateBlocking(userId.value, type.map())
312312
}
313313
}
314314

315-
override suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result<Boolean> {
316-
return runCatching {
317-
innerRoom.canUserSendMessage(userId.value, type.map())
315+
override suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result<Boolean> = withContext(roomMembersDispatcher) {
316+
runCatching {
317+
innerRoom.canUserSendMessageBlocking(userId.value, type.map())
318318
}
319319
}
320320

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package io.element.android.libraries.matrix.impl.sync
1818

19+
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
1920
import io.element.android.libraries.matrix.api.sync.SyncService
2021
import io.element.android.libraries.matrix.api.sync.SyncState
2122
import kotlinx.coroutines.CoroutineScope
@@ -25,27 +26,33 @@ import kotlinx.coroutines.flow.distinctUntilChanged
2526
import kotlinx.coroutines.flow.map
2627
import kotlinx.coroutines.flow.onEach
2728
import kotlinx.coroutines.flow.stateIn
29+
import kotlinx.coroutines.withContext
2830
import org.matrix.rustcomponents.sdk.SyncServiceInterface
2931
import org.matrix.rustcomponents.sdk.SyncServiceState
3032
import timber.log.Timber
3133

3234
class RustSyncService(
3335
private val innerSyncService: SyncServiceInterface,
36+
private val dispatchers: CoroutineDispatchers,
3437
sessionCoroutineScope: CoroutineScope
3538
) : SyncService {
3639

37-
override suspend fun startSync() = runCatching {
38-
Timber.i("Start sync")
39-
innerSyncService.start()
40-
}.onFailure {
41-
Timber.d("Start sync failed: $it")
40+
override suspend fun startSync() = withContext(dispatchers.io) {
41+
runCatching {
42+
Timber.i("Start sync")
43+
innerSyncService.startBlocking()
44+
}.onFailure {
45+
Timber.d("Start sync failed: $it")
46+
}
4247
}
4348

44-
override suspend fun stopSync() = runCatching {
45-
Timber.i("Stop sync")
46-
innerSyncService.stop()
47-
}.onFailure {
48-
Timber.d("Stop sync failed: $it")
49+
override suspend fun stopSync() = withContext(dispatchers.io){
50+
runCatching {
51+
Timber.i("Stop sync")
52+
innerSyncService.stopBlocking()
53+
}.onFailure {
54+
Timber.d("Stop sync failed: $it")
55+
}
4956
}
5057

5158
override val syncState: StateFlow<SyncState> =

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RoomTimelineExtensions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ internal fun Room.timelineDiffFlow(onInitialList: suspend (List<TimelineItem>) -
4444
}
4545
val roomId = id()
4646
Timber.d("Open timelineDiffFlow for room $roomId")
47-
val result = addTimelineListener(listener)
47+
val result = addTimelineListenerBlocking(listener)
4848
try {
4949
onInitialList(result.items)
5050
} catch (exception: Exception) {

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class RustMatrixTimeline(
124124

125125
private suspend fun fetchMembers() = withContext(dispatcher) {
126126
initLatch.await()
127-
innerRoom.fetchMembers()
127+
innerRoom.fetchMembersBlocking()
128128
}
129129

130130
@OptIn(ExperimentalCoroutinesApi::class)

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package io.element.android.libraries.matrix.impl.verification
1818

19+
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
1920
import io.element.android.libraries.core.data.tryOrNull
2021
import io.element.android.libraries.matrix.api.sync.SyncState
2122
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
@@ -27,6 +28,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
2728
import kotlinx.coroutines.flow.StateFlow
2829
import kotlinx.coroutines.flow.asStateFlow
2930
import kotlinx.coroutines.flow.combine
31+
import kotlinx.coroutines.withContext
3032
import org.matrix.rustcomponents.sdk.SessionVerificationController
3133
import org.matrix.rustcomponents.sdk.SessionVerificationControllerDelegate
3234
import org.matrix.rustcomponents.sdk.SessionVerificationControllerInterface
@@ -35,6 +37,7 @@ import javax.inject.Inject
3537

3638
class RustSessionVerificationService @Inject constructor(
3739
private val syncService: RustSyncService,
40+
private val dispatchers: CoroutineDispatchers,
3841
) : SessionVerificationService, SessionVerificationControllerDelegate {
3942

4043
var verificationController: SessionVerificationControllerInterface? = null
@@ -61,21 +64,31 @@ class RustSessionVerificationService @Inject constructor(
6164
syncState == SyncState.Running && verificationStatus == SessionVerifiedStatus.NotVerified
6265
}
6366

64-
override suspend fun requestVerification() = tryOrFail {
65-
verificationController?.requestVerification()
67+
override suspend fun requestVerification() {
68+
tryOrFail {
69+
verificationController?.requestVerificationBlocking()
70+
}
6671
}
6772

68-
override suspend fun cancelVerification() = tryOrFail { verificationController?.cancelVerification() }
73+
override suspend fun cancelVerification() {
74+
tryOrFail { verificationController?.cancelVerificationBlocking() }
75+
}
6976

70-
override suspend fun approveVerification() = tryOrFail { verificationController?.approveVerification() }
77+
override suspend fun approveVerification() {
78+
tryOrFail { verificationController?.approveVerificationBlocking() }
79+
}
7180

72-
override suspend fun declineVerification() = tryOrFail { verificationController?.declineVerification() }
81+
override suspend fun declineVerification() {
82+
tryOrFail { verificationController?.declineVerificationBlocking() }
83+
}
7384

74-
override suspend fun startVerification() = tryOrFail {
75-
verificationController?.startSasVerification()
85+
override suspend fun startVerification() {
86+
tryOrFail {
87+
verificationController?.startSasVerificationBlocking()
88+
}
7689
}
7790

78-
private suspend fun tryOrFail(block: suspend () -> Unit) {
91+
private suspend fun tryOrFail(block: suspend () -> Unit) = withContext(dispatchers.io) {
7992
runCatching {
8093
block()
8194
}.onFailure { didFail() }

0 commit comments

Comments
 (0)