mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 02:15:35 +03:00
Merge pull request #3018 from vector-im/feature/bma/improve_perf
Fix issue with Realm in UpdateTrustWorker
This commit is contained in:
commit
ef6e57066b
17 changed files with 66 additions and 63 deletions
|
@ -8,6 +8,7 @@ Improvements 🙌:
|
|||
-
|
||||
|
||||
Bugfix 🐛:
|
||||
- Fix regression in UpdateTrustWorker (introduced in 1.1.2)
|
||||
- Timeline : Fix ripple effect on text item and fix background color of separators.
|
||||
|
||||
Translations 🗣:
|
||||
|
|
|
@ -39,7 +39,7 @@ internal class GossipingWorkManager @Inject constructor(
|
|||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.startChain(startChain)
|
||||
.setInputData(data)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 10_000L, TimeUnit.MILLISECONDS)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.matrix.android.sdk.internal.task.TaskThread
|
|||
import org.matrix.android.sdk.internal.task.configureWith
|
||||
import org.matrix.android.sdk.internal.util.JsonCanonicalizer
|
||||
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.internal.util.logLimit
|
||||
import org.matrix.android.sdk.internal.worker.WorkerParamsFactory
|
||||
import org.matrix.olm.OlmPkSigning
|
||||
import org.matrix.olm.OlmUtility
|
||||
|
@ -750,7 +751,7 @@ internal class DefaultCrossSigningService @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onUsersDeviceUpdate(userIds: List<String>) {
|
||||
Timber.d("## CrossSigning - onUsersDeviceUpdate for ${userIds.size} users: $userIds")
|
||||
Timber.d("## CrossSigning - onUsersDeviceUpdate for users: ${userIds.logLimit()}")
|
||||
val workerParams = UpdateTrustWorker.Params(
|
||||
sessionId = sessionId,
|
||||
filename = updateTrustWorkerDataRepository.createParam(userIds)
|
||||
|
@ -759,7 +760,7 @@ internal class DefaultCrossSigningService @Inject constructor(
|
|||
|
||||
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<UpdateTrustWorker>()
|
||||
.setInputData(workerData)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 2_000L, TimeUnit.MILLISECONDS)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
|
||||
workManagerProvider.workManager
|
||||
|
|
|
@ -97,22 +97,17 @@ internal class UpdateTrustWorker(context: Context,
|
|||
// Unfortunately we don't have much info on what did exactly changed (is it the cross signing keys of that user,
|
||||
// or a new device?) So we check all again :/
|
||||
Timber.d("## CrossSigning - Updating trust for users: ${userList.logLimit()}")
|
||||
|
||||
Realm.getInstance(cryptoRealmConfiguration).use { cryptoRealm ->
|
||||
Realm.getInstance(sessionRealmConfiguration).use {
|
||||
updateTrust(userList, cryptoRealm)
|
||||
}
|
||||
}
|
||||
updateTrust(userList)
|
||||
}
|
||||
|
||||
cleanup(params)
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
private suspend fun updateTrust(userListParam: List<String>,
|
||||
cRealm: Realm) {
|
||||
private suspend fun updateTrust(userListParam: List<String>) {
|
||||
var userList = userListParam
|
||||
var myCrossSigningInfo: MXCrossSigningInfo? = null
|
||||
|
||||
// First we check that the users MSK are trusted by mine
|
||||
// After that we check the trust chain for each devices of each users
|
||||
awaitTransaction(cryptoRealmConfiguration) { cryptoRealm ->
|
||||
|
@ -203,38 +198,43 @@ internal class UpdateTrustWorker(context: Context,
|
|||
|
||||
// So Cross Signing keys trust is updated, device trust is updated
|
||||
// We can now update room shields? in the session DB?
|
||||
updateTrustStep2(userList, myCrossSigningInfo)
|
||||
}
|
||||
|
||||
private suspend fun updateTrustStep2(userList: List<String>, myCrossSigningInfo: MXCrossSigningInfo?) {
|
||||
Timber.d("## CrossSigning - Updating shields for impacted rooms...")
|
||||
awaitTransaction(sessionRealmConfiguration) { sessionRealm ->
|
||||
sessionRealm.where(RoomMemberSummaryEntity::class.java)
|
||||
.`in`(RoomMemberSummaryEntityFields.USER_ID, userList.toTypedArray())
|
||||
.distinct(RoomMemberSummaryEntityFields.ROOM_ID)
|
||||
.findAll()
|
||||
.map { it.roomId }
|
||||
.also { Timber.d("## CrossSigning - ... impacted rooms ${it.logLimit()}") }
|
||||
.forEach { roomId ->
|
||||
RoomSummaryEntity.where(sessionRealm, roomId)
|
||||
.equalTo(RoomSummaryEntityFields.IS_ENCRYPTED, true)
|
||||
.findFirst()
|
||||
?.let { roomSummary ->
|
||||
Timber.d("## CrossSigning - Check shield state for room $roomId")
|
||||
val allActiveRoomMembers = RoomMemberHelper(sessionRealm, roomId).getActiveRoomMemberIds()
|
||||
try {
|
||||
val updatedTrust = computeRoomShield(
|
||||
myCrossSigningInfo,
|
||||
cRealm,
|
||||
allActiveRoomMembers,
|
||||
roomSummary
|
||||
)
|
||||
if (roomSummary.roomEncryptionTrustLevel != updatedTrust) {
|
||||
Timber.d("## CrossSigning - Shield change detected for $roomId -> $updatedTrust")
|
||||
roomSummary.roomEncryptionTrustLevel = updatedTrust
|
||||
Realm.getInstance(cryptoRealmConfiguration).use { cryptoRealm ->
|
||||
sessionRealm.where(RoomMemberSummaryEntity::class.java)
|
||||
.`in`(RoomMemberSummaryEntityFields.USER_ID, userList.toTypedArray())
|
||||
.distinct(RoomMemberSummaryEntityFields.ROOM_ID)
|
||||
.findAll()
|
||||
.map { it.roomId }
|
||||
.also { Timber.d("## CrossSigning - ... impacted rooms ${it.logLimit()}") }
|
||||
.forEach { roomId ->
|
||||
RoomSummaryEntity.where(sessionRealm, roomId)
|
||||
.equalTo(RoomSummaryEntityFields.IS_ENCRYPTED, true)
|
||||
.findFirst()
|
||||
?.let { roomSummary ->
|
||||
Timber.d("## CrossSigning - Check shield state for room $roomId")
|
||||
val allActiveRoomMembers = RoomMemberHelper(sessionRealm, roomId).getActiveRoomMemberIds()
|
||||
try {
|
||||
val updatedTrust = computeRoomShield(
|
||||
myCrossSigningInfo,
|
||||
cryptoRealm,
|
||||
allActiveRoomMembers,
|
||||
roomSummary
|
||||
)
|
||||
if (roomSummary.roomEncryptionTrustLevel != updatedTrust) {
|
||||
Timber.d("## CrossSigning - Shield change detected for $roomId -> $updatedTrust")
|
||||
roomSummary.roomEncryptionTrustLevel = updatedTrust
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure)
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ internal class CrossSigningKeysMapper @Inject constructor(moshi: Moshi) {
|
|||
return CryptoCrossSigningKey(
|
||||
userId = userId ?: "",
|
||||
keys = mapOf("ed25519:$pubKey" to pubKey),
|
||||
usages = keyInfo.usages.map { it },
|
||||
usages = keyInfo.usages.toList(),
|
||||
signatures = deserializeSignatures(keyInfo.signatures),
|
||||
trustLevel = keyInfo.trustLevelEntity?.let {
|
||||
DeviceTrustLevel(
|
||||
|
|
|
@ -183,7 +183,7 @@ internal class VerificationTransportRoomMessage(
|
|||
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SendVerificationMessageWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setInputData(workerParams)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 2_000L, TimeUnit.MILLISECONDS)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
|
||||
workManagerProvider.workManager
|
||||
|
@ -280,7 +280,7 @@ internal class VerificationTransportRoomMessage(
|
|||
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SendVerificationMessageWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setInputData(workerParams)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 2_000L, TimeUnit.MILLISECONDS)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
return workManagerProvider.workManager
|
||||
.beginUniqueWork(uniqueQueueName(), ExistingWorkPolicy.APPEND_OR_REPLACE, workRequest)
|
||||
|
|
|
@ -23,6 +23,7 @@ import androidx.work.NetworkType
|
|||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.WorkRequest
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -69,6 +70,7 @@ internal class WorkManagerProvider @Inject constructor(
|
|||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||
.build()
|
||||
|
||||
const val BACKOFF_DELAY = 10_000L
|
||||
// Use min value, smaller value will be ignored
|
||||
const val BACKOFF_DELAY_MILLIS = WorkRequest.MIN_BACKOFF_MILLIS
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ internal class DefaultPushersService @Inject constructor(
|
|||
val request = workManagerProvider.matrixOneTimeWorkRequestBuilder<AddHttpPusherWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setInputData(WorkerParamsFactory.toData(params))
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 10_000L, TimeUnit.MILLISECONDS)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
workManagerProvider.workManager.enqueue(request)
|
||||
return request.id
|
||||
|
|
|
@ -318,7 +318,7 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.startChain(true)
|
||||
.setInputData(uploadWorkData)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY, TimeUnit.MILLISECONDS)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
@ -332,7 +332,7 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
// .setConstraints(WorkManagerProvider.workConstraints)
|
||||
.startChain(false)
|
||||
.setInputData(workData)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY, TimeUnit.MILLISECONDS)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ internal class TimelineSendEventWorkCommon @Inject constructor(
|
|||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.startChain(startChain)
|
||||
.setInputData(data)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, BACKOFF_DELAY, TimeUnit.MILLISECONDS)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,5 @@ internal class TimelineSendEventWorkCommon @Inject constructor(
|
|||
|
||||
companion object {
|
||||
private const val SEND_WORK = "SEND_WORK"
|
||||
private const val BACKOFF_DELAY = 10_000L
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ internal class FileInitialSyncStatusRepository(directory: File) : InitialSyncSta
|
|||
val state = cache?.step ?: InitialSyncStatus.STEP_INIT
|
||||
return if (state >= InitialSyncStatus.STEP_DOWNLOADED
|
||||
&& System.currentTimeMillis() > (cache?.downloadedDate ?: 0) + INIT_SYNC_FILE_LIFETIME) {
|
||||
Timber.v("INIT_SYNC downloaded file is outdated, download it again")
|
||||
Timber.d("INIT_SYNC downloaded file is outdated, download it again")
|
||||
// The downloaded file is outdated
|
||||
setStep(InitialSyncStatus.STEP_INIT)
|
||||
InitialSyncStatus.STEP_INIT
|
||||
|
|
|
@ -147,13 +147,13 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
|||
if (numberOfChunks > 1) {
|
||||
reportSubtask(reporter, InitSyncStep.ImportingAccountJoinedRooms, numberOfChunks, 0.6f) {
|
||||
val chunkSize = listSize / numberOfChunks
|
||||
Timber.v("INIT_SYNC $listSize rooms to insert, split into $numberOfChunks sublists of $chunkSize items")
|
||||
Timber.d("INIT_SYNC $listSize rooms to insert, split into $numberOfChunks sublists of $chunkSize items")
|
||||
// I cannot find a better way to chunk a map, so chunk the keys and then create new maps
|
||||
handlingStrategy.data.keys
|
||||
.chunked(chunkSize)
|
||||
.forEachIndexed { index, roomIds ->
|
||||
val roomEntities = roomIds
|
||||
.also { Timber.v("INIT_SYNC insert ${roomIds.size} rooms") }
|
||||
.also { Timber.d("INIT_SYNC insert ${roomIds.size} rooms") }
|
||||
.map {
|
||||
handleJoinedRoom(
|
||||
realm = realm,
|
||||
|
|
|
@ -101,7 +101,7 @@ internal class DefaultSyncTask @Inject constructor(
|
|||
val readTimeOut = (params.timeout + TIMEOUT_MARGIN).coerceAtLeast(TimeOutInterceptor.DEFAULT_LONG_TIMEOUT)
|
||||
|
||||
if (isInitialSync) {
|
||||
Timber.v("INIT_SYNC with filter: ${requestParams["filter"]}")
|
||||
Timber.d("INIT_SYNC with filter: ${requestParams["filter"]}")
|
||||
val initSyncStrategy = initialSyncStrategy
|
||||
logDuration("INIT_SYNC strategy: $initSyncStrategy") {
|
||||
if (initSyncStrategy is InitialSyncStrategy.Optimized) {
|
||||
|
@ -145,7 +145,7 @@ internal class DefaultSyncTask @Inject constructor(
|
|||
val workingFile = File(workingDir, "initSync.json")
|
||||
val status = initialSyncStatusRepository.getStep()
|
||||
if (workingFile.exists() && status >= InitialSyncStatus.STEP_DOWNLOADED) {
|
||||
Timber.v("INIT_SYNC file is already here")
|
||||
Timber.d("INIT_SYNC file is already here")
|
||||
reportSubtask(initialSyncProgressService, InitSyncStep.Downloading, 1, 0.3f) {
|
||||
// Empty task
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ internal class DefaultSyncTask @Inject constructor(
|
|||
// Log some stats
|
||||
val nbOfJoinedRooms = syncResponse.rooms?.join?.size ?: 0
|
||||
val nbOfJoinedRoomsInFile = syncResponse.rooms?.join?.values?.count { it.ephemeral is LazyRoomSyncEphemeral.Stored }
|
||||
Timber.v("INIT_SYNC $nbOfJoinedRooms rooms, $nbOfJoinedRoomsInFile ephemeral stored into files")
|
||||
Timber.d("INIT_SYNC $nbOfJoinedRooms rooms, $nbOfJoinedRoomsInFile ephemeral stored into files")
|
||||
|
||||
logDuration("INIT_SYNC Database insertion") {
|
||||
syncResponseHandler.handleResponse(syncResponse, null, initialSyncProgressService)
|
||||
|
|
|
@ -106,7 +106,7 @@ internal class SyncWorker(context: Context,
|
|||
val data = WorkerParamsFactory.toData(Params(sessionId, serverTimeout, 0L, false))
|
||||
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SyncWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 1_000, TimeUnit.MILLISECONDS)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.setInputData(data)
|
||||
.build()
|
||||
workManagerProvider.workManager
|
||||
|
@ -118,7 +118,7 @@ internal class SyncWorker(context: Context,
|
|||
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SyncWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setInputData(data)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 1_000, TimeUnit.MILLISECONDS)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.setInitialDelay(delayInSeconds, TimeUnit.SECONDS)
|
||||
.build()
|
||||
|
||||
|
|
|
@ -57,12 +57,12 @@ internal class SplitLazyRoomSyncEphemeralJsonAdapter(
|
|||
}
|
||||
val limit = syncStrategy.minSizeToStoreInFile
|
||||
return if (json.length > limit) {
|
||||
Timber.v("INIT_SYNC $path content length: ${json.length} copy to a file")
|
||||
Timber.d("INIT_SYNC $path content length: ${json.length} copy to a file")
|
||||
// Copy the source to a file
|
||||
roomSyncEphemeralTemporaryStore.write(roomId, json)
|
||||
LazyRoomSyncEphemeral.Stored
|
||||
} else {
|
||||
Timber.v("INIT_SYNC $path content length: ${json.length} parse it now")
|
||||
Timber.d("INIT_SYNC $path content length: ${json.length} parse it now")
|
||||
val roomSync = delegate.fromJson(json) ?: return null
|
||||
LazyRoomSyncEphemeral.Parsed(roomSync)
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@ internal class InitialSyncResponseParser @Inject constructor(
|
|||
|
||||
fun parse(syncStrategy: InitialSyncStrategy.Optimized, workingFile: File): SyncResponse {
|
||||
val syncResponseLength = workingFile.length().toInt()
|
||||
Timber.v("INIT_SYNC Sync file size is $syncResponseLength bytes")
|
||||
Timber.d("INIT_SYNC Sync file size is $syncResponseLength bytes")
|
||||
val shouldSplit = syncResponseLength >= syncStrategy.minSizeToSplit
|
||||
Timber.v("INIT_SYNC should split in several files: $shouldSplit")
|
||||
Timber.d("INIT_SYNC should split in several files: $shouldSplit")
|
||||
return getMoshi(syncStrategy, shouldSplit)
|
||||
.adapter(SyncResponse::class.java)
|
||||
.fromJson(workingFile.source().buffer())!!
|
||||
|
|
|
@ -33,13 +33,13 @@ internal fun <T> Collection<T>.logLimit(maxQuantity: Int = 5): String {
|
|||
|
||||
internal suspend fun <T> logDuration(message: String,
|
||||
block: suspend () -> T): T {
|
||||
Timber.v("$message -- BEGIN")
|
||||
Timber.d("$message -- BEGIN")
|
||||
val start = System.currentTimeMillis()
|
||||
val result = logRamUsage(message) {
|
||||
block()
|
||||
}
|
||||
val duration = System.currentTimeMillis() - start
|
||||
Timber.v("$message -- END duration: $duration ms")
|
||||
Timber.d("$message -- END duration: $duration ms")
|
||||
|
||||
return result
|
||||
}
|
||||
|
@ -50,12 +50,12 @@ internal suspend fun <T> logRamUsage(message: String, block: suspend () -> T): T
|
|||
runtime.gc()
|
||||
val freeMemoryInMb = runtime.freeMemory() / 1048576L
|
||||
val usedMemInMBStart = runtime.totalMemory() / 1048576L - freeMemoryInMb
|
||||
Timber.v("$message -- BEGIN (free memory: $freeMemoryInMb MB)")
|
||||
Timber.d("$message -- BEGIN (free memory: $freeMemoryInMb MB)")
|
||||
val result = block()
|
||||
runtime.gc()
|
||||
val usedMemInMBEnd = (runtime.totalMemory() - runtime.freeMemory()) / 1048576L
|
||||
val usedMemInMBDiff = usedMemInMBEnd - usedMemInMBStart
|
||||
Timber.v("$message -- END RAM usage: $usedMemInMBDiff MB")
|
||||
Timber.d("$message -- END RAM usage: $usedMemInMBDiff MB")
|
||||
result
|
||||
} else {
|
||||
block()
|
||||
|
|
Loading…
Reference in a new issue