Adjust metrics to the new specifications (#5937)

* Add `AnalyticsTransactions` with a set of `TransactionDefinition` items matching those in the user story

* Use that for `AnalyticsLongRunningTransactions`, make sure we send the right fields (name, operation, description)

* Add `AnalyticsSendMessageWatcher` to track how long it takes for an event to be sent and for us to get a call back for that from sync

* Add `Noop` implementation for enterprise
This commit is contained in:
Jorge Martin Espinosa
2026-01-05 16:23:26 +01:00
committed by GitHub
parent bc62d4c8ba
commit 71031008dd
33 changed files with 443 additions and 48 deletions

View File

@@ -177,4 +177,9 @@ interface JoinedRoom : BaseRoom {
*
*/
suspend fun withdrawVerificationAndResend(userIds: List<UserId>, sendHandle: SendHandle): Result<Unit>
/**
* Subscribe to a [Flow] of [SendQueueUpdate] related to this room.
*/
fun subscribeToSendQueueUpdates(): Flow<SendQueueUpdate>
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.api.room
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.TransactionId
import io.element.android.libraries.matrix.api.media.MediaSource
sealed interface SendQueueUpdate {
data class NewLocalEvent(val transactionId: TransactionId) : SendQueueUpdate
data class CancelledLocalEvent(val transactionId: TransactionId) : SendQueueUpdate
data class ReplacedLocalEvent(val transactionId: TransactionId) : SendQueueUpdate
data class SendError(val transactionId: TransactionId) : SendQueueUpdate
data class RetrySendingEvent(val transactionId: TransactionId) : SendQueueUpdate
data class SentEvent(val transactionId: TransactionId, val eventId: EventId) : SendQueueUpdate
data class MediaUpload(val relatedTo: EventId, val file: MediaSource?, val index: Long, val progress: Float) : SendQueueUpdate
}

View File

@@ -26,6 +26,7 @@ import io.element.android.libraries.matrix.api.room.CreateTimelineParams
import io.element.android.libraries.matrix.api.room.IntentionalMention
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomNotificationSettingsState
import io.element.android.libraries.matrix.api.room.SendQueueUpdate
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.room.knock.KnockRequest
@@ -66,6 +67,8 @@ import org.matrix.rustcomponents.sdk.DateDividerMode
import org.matrix.rustcomponents.sdk.IdentityStatusChangeListener
import org.matrix.rustcomponents.sdk.KnockRequestsListener
import org.matrix.rustcomponents.sdk.RoomMessageEventMessageType
import org.matrix.rustcomponents.sdk.RoomSendQueueUpdate
import org.matrix.rustcomponents.sdk.SendQueueListener
import org.matrix.rustcomponents.sdk.TimelineConfiguration
import org.matrix.rustcomponents.sdk.TimelineFilter
import org.matrix.rustcomponents.sdk.TimelineFocus
@@ -486,6 +489,16 @@ class JoinedRustRoom(
}
}
override fun subscribeToSendQueueUpdates(): Flow<SendQueueUpdate> {
return mxCallbackFlow {
innerRoom.subscribeToSendQueueUpdates(object : SendQueueListener {
override fun onUpdate(update: RoomSendQueueUpdate) {
trySend(update.map())
}
})
}
}
override fun close() = destroy()
override fun destroy() {

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.room
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.TransactionId
import io.element.android.libraries.matrix.api.room.SendQueueUpdate
import io.element.android.libraries.matrix.impl.media.map
import org.matrix.rustcomponents.sdk.RoomSendQueueUpdate
fun RoomSendQueueUpdate.map(): SendQueueUpdate = when (this) {
is RoomSendQueueUpdate.NewLocalEvent -> SendQueueUpdate.NewLocalEvent(TransactionId(transactionId))
is RoomSendQueueUpdate.CancelledLocalEvent -> SendQueueUpdate.CancelledLocalEvent(TransactionId(transactionId))
is RoomSendQueueUpdate.MediaUpload -> SendQueueUpdate.MediaUpload(
relatedTo = EventId(relatedTo),
file = file?.map(),
index = index.toLong(),
progress = progress.current.toFloat() / progress.total.toFloat(),
)
is RoomSendQueueUpdate.ReplacedLocalEvent -> SendQueueUpdate.ReplacedLocalEvent(TransactionId(transactionId))
is RoomSendQueueUpdate.RetryEvent -> SendQueueUpdate.RetrySendingEvent(TransactionId(transactionId))
is RoomSendQueueUpdate.SendError -> SendQueueUpdate.SendError(TransactionId(transactionId))
is RoomSendQueueUpdate.SentEvent -> SendQueueUpdate.SentEvent(TransactionId(transactionId), EventId(eventId))
}

View File

@@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomMembersState
import io.element.android.libraries.matrix.api.room.RoomNotificationSettingsState
import io.element.android.libraries.matrix.api.room.SendQueueUpdate
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.room.knock.KnockRequest
@@ -39,6 +40,7 @@ import io.element.android.tests.testutils.simulateLongTask
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.test.TestScope
@@ -83,6 +85,8 @@ class FakeJoinedRoom(
private val updateJoinRuleResult: (JoinRule) -> Result<Unit> = { lambdaError() },
private val setSendQueueEnabledResult: (Boolean) -> Unit = { _: Boolean -> },
) : JoinedRoom, BaseRoom by baseRoom {
private val sendQueueUpdates = MutableSharedFlow<SendQueueUpdate>(extraBufferCapacity = 10)
fun givenRoomMembersState(state: RoomMembersState) {
baseRoom.givenRoomMembersState(state)
}
@@ -219,6 +223,10 @@ class FakeJoinedRoom(
withdrawVerificationAndResendResult(userIds, sendHandle)
}
override fun subscribeToSendQueueUpdates(): Flow<SendQueueUpdate> {
return sendQueueUpdates
}
private suspend fun simulateSendMediaProgress(progressCallback: ProgressCallback?) {
progressCallbackValues.forEach { (current, total) ->
progressCallback?.onProgress(current, total)
@@ -229,4 +237,8 @@ class FakeJoinedRoom(
fun emitSyncUpdate() {
(syncUpdateFlow as MutableStateFlow).value = syncUpdateFlow.value + 1
}
suspend fun givenSendQueueUpdate(sendQueueUpdate: SendQueueUpdate) {
sendQueueUpdates.emit(sendQueueUpdate)
}
}