Merge pull request #7985 from vector-im/feature/bma/slowDownSentry
Slow down sentry
This commit is contained in:
commit
3fcf2a1dd8
1
changelog.d/7960.misc
Normal file
1
changelog.d/7960.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Sentry: Report sync duration and metrics for initial sync and for sync after pause. Not for regular sync.
|
@ -43,6 +43,27 @@ inline fun List<MetricPlugin>.measureMetric(block: () -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the given [block] while measuring the transaction.
|
||||||
|
*
|
||||||
|
* @param block Action/Task to be executed within this span.
|
||||||
|
*/
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
inline fun List<SpannableMetricPlugin>.measureSpannableMetric(block: List<SpannableMetricPlugin>.() -> Unit) {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.forEach { plugin -> plugin.startTransaction() } // Start the transaction.
|
||||||
|
block()
|
||||||
|
} catch (throwable: Throwable) {
|
||||||
|
this.forEach { plugin -> plugin.onError(throwable) } // Capture if there is any exception thrown.
|
||||||
|
throw throwable
|
||||||
|
} finally {
|
||||||
|
this.forEach { plugin -> plugin.finishTransaction() } // Finally, finish this transaction.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the given [block] while measuring a span.
|
* Executes the given [block] while measuring a span.
|
||||||
*
|
*
|
||||||
|
@ -29,4 +29,6 @@ interface SyncDurationMetricPlugin : SpannableMetricPlugin {
|
|||||||
override fun logTransaction(message: String?) {
|
override fun logTransaction(message: String?) {
|
||||||
Timber.tag(loggerTag.value).v("## syncResponseHandler() : $message")
|
Timber.tag(loggerTag.value).v("## syncResponseHandler() : $message")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun shouldReport(isInitialSync: Boolean, isAfterPause: Boolean): Boolean = true
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,9 @@ package org.matrix.android.sdk.internal.session.sync
|
|||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
import org.matrix.android.sdk.api.MatrixConfiguration
|
import org.matrix.android.sdk.api.MatrixConfiguration
|
||||||
import org.matrix.android.sdk.api.extensions.measureMetric
|
|
||||||
import org.matrix.android.sdk.api.extensions.measureSpan
|
import org.matrix.android.sdk.api.extensions.measureSpan
|
||||||
|
import org.matrix.android.sdk.api.extensions.measureSpannableMetric
|
||||||
|
import org.matrix.android.sdk.api.metrics.SpannableMetricPlugin
|
||||||
import org.matrix.android.sdk.api.metrics.SyncDurationMetricPlugin
|
import org.matrix.android.sdk.api.metrics.SyncDurationMetricPlugin
|
||||||
import org.matrix.android.sdk.api.session.pushrules.PushRuleService
|
import org.matrix.android.sdk.api.session.pushrules.PushRuleService
|
||||||
import org.matrix.android.sdk.api.session.pushrules.RuleScope
|
import org.matrix.android.sdk.api.session.pushrules.RuleScope
|
||||||
@ -67,12 +68,13 @@ internal class SyncResponseHandler @Inject constructor(
|
|||||||
suspend fun handleResponse(
|
suspend fun handleResponse(
|
||||||
syncResponse: SyncResponse,
|
syncResponse: SyncResponse,
|
||||||
fromToken: String?,
|
fromToken: String?,
|
||||||
|
afterPause: Boolean,
|
||||||
reporter: ProgressReporter?
|
reporter: ProgressReporter?
|
||||||
) {
|
) {
|
||||||
val isInitialSync = fromToken == null
|
val isInitialSync = fromToken == null
|
||||||
Timber.v("Start handling sync, is InitialSync: $isInitialSync")
|
Timber.v("Start handling sync, is InitialSync: $isInitialSync")
|
||||||
|
|
||||||
relevantPlugins.measureMetric {
|
relevantPlugins.filter { it.shouldReport(isInitialSync, afterPause) }.measureSpannableMetric {
|
||||||
startCryptoService(isInitialSync)
|
startCryptoService(isInitialSync)
|
||||||
|
|
||||||
// Handle the to device events before the room ones
|
// Handle the to device events before the room ones
|
||||||
@ -101,8 +103,8 @@ internal class SyncResponseHandler @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startCryptoService(isInitialSync: Boolean) {
|
private fun List<SpannableMetricPlugin>.startCryptoService(isInitialSync: Boolean) {
|
||||||
relevantPlugins.measureSpan("task", "start_crypto_service") {
|
measureSpan("task", "start_crypto_service") {
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
if (!cryptoService.isStarted()) {
|
if (!cryptoService.isStarted()) {
|
||||||
Timber.v("Should start cryptoService")
|
Timber.v("Should start cryptoService")
|
||||||
@ -115,8 +117,8 @@ internal class SyncResponseHandler @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun handleToDevice(syncResponse: SyncResponse, reporter: ProgressReporter?) {
|
private suspend fun List<SpannableMetricPlugin>.handleToDevice(syncResponse: SyncResponse, reporter: ProgressReporter?) {
|
||||||
relevantPlugins.measureSpan("task", "handle_to_device") {
|
measureSpan("task", "handle_to_device") {
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
Timber.v("Handle toDevice")
|
Timber.v("Handle toDevice")
|
||||||
reportSubtask(reporter, InitialSyncStep.ImportingAccountCrypto, 100, 0.1f) {
|
reportSubtask(reporter, InitialSyncStep.ImportingAccountCrypto, 100, 0.1f) {
|
||||||
@ -130,14 +132,14 @@ internal class SyncResponseHandler @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun startMonarchyTransaction(
|
private suspend fun List<SpannableMetricPlugin>.startMonarchyTransaction(
|
||||||
syncResponse: SyncResponse,
|
syncResponse: SyncResponse,
|
||||||
isInitialSync: Boolean,
|
isInitialSync: Boolean,
|
||||||
reporter: ProgressReporter?,
|
reporter: ProgressReporter?,
|
||||||
aggregator: SyncResponsePostTreatmentAggregator
|
aggregator: SyncResponsePostTreatmentAggregator
|
||||||
) {
|
) {
|
||||||
// Start one big transaction
|
// Start one big transaction
|
||||||
relevantPlugins.measureSpan("task", "monarchy_transaction") {
|
measureSpan("task", "monarchy_transaction") {
|
||||||
monarchy.awaitTransaction { realm ->
|
monarchy.awaitTransaction { realm ->
|
||||||
// IMPORTANT nothing should be suspend here as we are accessing the realm instance (thread local)
|
// IMPORTANT nothing should be suspend here as we are accessing the realm instance (thread local)
|
||||||
handleRooms(reporter, syncResponse, realm, isInitialSync, aggregator)
|
handleRooms(reporter, syncResponse, realm, isInitialSync, aggregator)
|
||||||
@ -149,14 +151,14 @@ internal class SyncResponseHandler @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleRooms(
|
private fun List<SpannableMetricPlugin>.handleRooms(
|
||||||
reporter: ProgressReporter?,
|
reporter: ProgressReporter?,
|
||||||
syncResponse: SyncResponse,
|
syncResponse: SyncResponse,
|
||||||
realm: Realm,
|
realm: Realm,
|
||||||
isInitialSync: Boolean,
|
isInitialSync: Boolean,
|
||||||
aggregator: SyncResponsePostTreatmentAggregator
|
aggregator: SyncResponsePostTreatmentAggregator
|
||||||
) {
|
) {
|
||||||
relevantPlugins.measureSpan("task", "handle_rooms") {
|
measureSpan("task", "handle_rooms") {
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
Timber.v("Handle rooms")
|
Timber.v("Handle rooms")
|
||||||
reportSubtask(reporter, InitialSyncStep.ImportingAccountRoom, 1, 0.8f) {
|
reportSubtask(reporter, InitialSyncStep.ImportingAccountRoom, 1, 0.8f) {
|
||||||
@ -170,8 +172,8 @@ internal class SyncResponseHandler @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleAccountData(reporter: ProgressReporter?, realm: Realm, syncResponse: SyncResponse) {
|
private fun List<SpannableMetricPlugin>.handleAccountData(reporter: ProgressReporter?, realm: Realm, syncResponse: SyncResponse) {
|
||||||
relevantPlugins.measureSpan("task", "handle_account_data") {
|
measureSpan("task", "handle_account_data") {
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
reportSubtask(reporter, InitialSyncStep.ImportingAccountData, 1, 0.1f) {
|
reportSubtask(reporter, InitialSyncStep.ImportingAccountData, 1, 0.1f) {
|
||||||
Timber.v("Handle accountData")
|
Timber.v("Handle accountData")
|
||||||
@ -183,8 +185,8 @@ internal class SyncResponseHandler @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handlePresence(realm: Realm, syncResponse: SyncResponse) {
|
private fun List<SpannableMetricPlugin>.handlePresence(realm: Realm, syncResponse: SyncResponse) {
|
||||||
relevantPlugins.measureSpan("task", "handle_presence") {
|
measureSpan("task", "handle_presence") {
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
Timber.v("Handle Presence")
|
Timber.v("Handle Presence")
|
||||||
presenceSyncHandler.handle(realm, syncResponse.presence)
|
presenceSyncHandler.handle(realm, syncResponse.presence)
|
||||||
@ -194,8 +196,8 @@ internal class SyncResponseHandler @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun aggregateSyncResponse(aggregator: SyncResponsePostTreatmentAggregator) {
|
private suspend fun List<SpannableMetricPlugin>.aggregateSyncResponse(aggregator: SyncResponsePostTreatmentAggregator) {
|
||||||
relevantPlugins.measureSpan("task", "aggregator_management") {
|
measureSpan("task", "aggregator_management") {
|
||||||
// Everything else we need to do outside the transaction
|
// Everything else we need to do outside the transaction
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
aggregatorHandler.handle(aggregator)
|
aggregatorHandler.handle(aggregator)
|
||||||
@ -205,8 +207,8 @@ internal class SyncResponseHandler @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun postTreatmentSyncResponse(syncResponse: SyncResponse, isInitialSync: Boolean) {
|
private suspend fun List<SpannableMetricPlugin>.postTreatmentSyncResponse(syncResponse: SyncResponse, isInitialSync: Boolean) {
|
||||||
relevantPlugins.measureSpan("task", "sync_response_post_treatment") {
|
measureSpan("task", "sync_response_post_treatment") {
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
syncResponse.rooms?.let {
|
syncResponse.rooms?.let {
|
||||||
checkPushRules(it, isInitialSync)
|
checkPushRules(it, isInitialSync)
|
||||||
@ -219,8 +221,8 @@ internal class SyncResponseHandler @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun markCryptoSyncCompleted(syncResponse: SyncResponse, cryptoStoreAggregator: CryptoStoreAggregator) {
|
private fun List<SpannableMetricPlugin>.markCryptoSyncCompleted(syncResponse: SyncResponse, cryptoStoreAggregator: CryptoStoreAggregator) {
|
||||||
relevantPlugins.measureSpan("task", "crypto_sync_handler_onSyncCompleted") {
|
measureSpan("task", "crypto_sync_handler_onSyncCompleted") {
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
cryptoSyncHandler.onSyncCompleted(syncResponse, cryptoStoreAggregator)
|
cryptoSyncHandler.onSyncCompleted(syncResponse, cryptoStoreAggregator)
|
||||||
}.also {
|
}.also {
|
||||||
|
@ -151,7 +151,7 @@ internal class DefaultSyncTask @Inject constructor(
|
|||||||
syncStatisticsData.requestInitSyncTime = SystemClock.elapsedRealtime()
|
syncStatisticsData.requestInitSyncTime = SystemClock.elapsedRealtime()
|
||||||
syncStatisticsData.downloadInitSyncTime = syncStatisticsData.requestInitSyncTime
|
syncStatisticsData.downloadInitSyncTime = syncStatisticsData.requestInitSyncTime
|
||||||
logDuration("INIT_SYNC Database insertion", loggerTag, clock) {
|
logDuration("INIT_SYNC Database insertion", loggerTag, clock) {
|
||||||
syncResponseHandler.handleResponse(syncResponse, token, syncRequestStateTracker)
|
syncResponseHandler.handleResponse(syncResponse, null, afterPause = true, syncRequestStateTracker)
|
||||||
}
|
}
|
||||||
syncResponseToReturn = syncResponse
|
syncResponseToReturn = syncResponse
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ internal class DefaultSyncTask @Inject constructor(
|
|||||||
toDevice = nbToDevice,
|
toDevice = nbToDevice,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
syncResponseHandler.handleResponse(syncResponse, token, null)
|
syncResponseHandler.handleResponse(syncResponse, token, afterPause = params.afterPause, null)
|
||||||
syncResponseToReturn = syncResponse
|
syncResponseToReturn = syncResponse
|
||||||
Timber.tag(loggerTag.value).d("Incremental sync done")
|
Timber.tag(loggerTag.value).d("Incremental sync done")
|
||||||
syncRequestStateTracker.setSyncRequestState(SyncRequestState.IncrementalSyncDone)
|
syncRequestStateTracker.setSyncRequestState(SyncRequestState.IncrementalSyncDone)
|
||||||
@ -264,7 +264,7 @@ internal class DefaultSyncTask @Inject constructor(
|
|||||||
Timber.tag(loggerTag.value).d("INIT_SYNC $nbOfJoinedRooms rooms, $nbOfJoinedRoomsInFile ephemeral stored into files")
|
Timber.tag(loggerTag.value).d("INIT_SYNC $nbOfJoinedRooms rooms, $nbOfJoinedRoomsInFile ephemeral stored into files")
|
||||||
|
|
||||||
logDuration("INIT_SYNC Database insertion", loggerTag, clock) {
|
logDuration("INIT_SYNC Database insertion", loggerTag, clock) {
|
||||||
syncResponseHandler.handleResponse(syncResponse, null, syncRequestStateTracker)
|
syncResponseHandler.handleResponse(syncResponse, null, afterPause = true, syncRequestStateTracker)
|
||||||
}
|
}
|
||||||
initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_SUCCESS)
|
initialSyncStatusRepository.setStep(InitialSyncStatus.STEP_SUCCESS)
|
||||||
syncResponse
|
syncResponse
|
||||||
|
@ -34,6 +34,11 @@ class SentrySyncDurationMetrics @Inject constructor() : SyncDurationMetricPlugin
|
|||||||
// Stacks to keep spans in LIFO order.
|
// Stacks to keep spans in LIFO order.
|
||||||
private var spans: Stack<ISpan> = Stack()
|
private var spans: Stack<ISpan> = Stack()
|
||||||
|
|
||||||
|
override fun shouldReport(isInitialSync: Boolean, isAfterPause: Boolean): Boolean {
|
||||||
|
// Report only for initial sync and for sync after pause
|
||||||
|
return isInitialSync || isAfterPause
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the span for a sub-task.
|
* Starts the span for a sub-task.
|
||||||
*
|
*
|
||||||
@ -69,6 +74,7 @@ class SentrySyncDurationMetrics @Inject constructor() : SyncDurationMetricPlugin
|
|||||||
|
|
||||||
override fun finishTransaction() {
|
override fun finishTransaction() {
|
||||||
transaction?.finish()
|
transaction?.finish()
|
||||||
|
transaction = null
|
||||||
logTransaction("Sentry transaction finished")
|
logTransaction("Sentry transaction finished")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user