fix backup looping same keys
This commit is contained in:
parent
448b6e1c74
commit
309642845e
|
@ -24,7 +24,6 @@ import org.junit.Assert.assertNotNull
|
||||||
import org.junit.Assert.assertNull
|
import org.junit.Assert.assertNull
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.FixMethodOrder
|
import org.junit.FixMethodOrder
|
||||||
import org.junit.Ignore
|
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
@ -56,7 +55,6 @@ import java.util.concurrent.CountDownLatch
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
@FixMethodOrder(MethodSorters.JVM)
|
@FixMethodOrder(MethodSorters.JVM)
|
||||||
@LargeTest
|
@LargeTest
|
||||||
@Ignore
|
|
||||||
class KeysBackupTest : InstrumentedTest {
|
class KeysBackupTest : InstrumentedTest {
|
||||||
|
|
||||||
@get:Rule val rule = RetryTestRule(3)
|
@get:Rule val rule = RetryTestRule(3)
|
||||||
|
|
|
@ -21,13 +21,10 @@ import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
|
||||||
import org.matrix.android.sdk.api.logger.LoggerTag
|
import org.matrix.android.sdk.api.logger.LoggerTag
|
||||||
import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper
|
import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrapper
|
||||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.Timer
|
|
||||||
import java.util.TimerTask
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal data class InboundGroupSessionHolder(
|
internal data class InboundGroupSessionHolder(
|
||||||
|
@ -57,18 +54,13 @@ internal class InboundGroupSessionStore @Inject constructor(
|
||||||
if (oldValue != null) {
|
if (oldValue != null) {
|
||||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||||
Timber.tag(loggerTag.value).v("## Inbound: entryRemoved ${oldValue.wrapper.roomId}-${oldValue.wrapper.senderKey}")
|
Timber.tag(loggerTag.value).v("## Inbound: entryRemoved ${oldValue.wrapper.roomId}-${oldValue.wrapper.senderKey}")
|
||||||
store.storeInboundGroupSessions(listOf(oldValue).map { it.wrapper })
|
// store.storeInboundGroupSessions(listOf(oldValue).map { it.wrapper })
|
||||||
oldValue.wrapper.session.releaseSession()
|
oldValue.wrapper.session.releaseSession()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val timer = Timer()
|
|
||||||
private var timerTask: TimerTask? = null
|
|
||||||
|
|
||||||
private val dirtySession = mutableListOf<InboundGroupSessionHolder>()
|
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun clear() {
|
fun clear() {
|
||||||
sessionCache.evictAll()
|
sessionCache.evictAll()
|
||||||
|
@ -90,7 +82,6 @@ internal class InboundGroupSessionStore @Inject constructor(
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun replaceGroupSession(old: InboundGroupSessionHolder, new: InboundGroupSessionHolder, sessionId: String, senderKey: String) {
|
fun replaceGroupSession(old: InboundGroupSessionHolder, new: InboundGroupSessionHolder, sessionId: String, senderKey: String) {
|
||||||
Timber.tag(loggerTag.value).v("## Replacing outdated session ${old.wrapper.roomId}-${old.wrapper.senderKey}")
|
Timber.tag(loggerTag.value).v("## Replacing outdated session ${old.wrapper.roomId}-${old.wrapper.senderKey}")
|
||||||
dirtySession.remove(old)
|
|
||||||
store.removeInboundGroupSession(sessionId, senderKey)
|
store.removeInboundGroupSession(sessionId, senderKey)
|
||||||
sessionCache.remove(CacheKey(sessionId, senderKey))
|
sessionCache.remove(CacheKey(sessionId, senderKey))
|
||||||
|
|
||||||
|
@ -107,33 +98,14 @@ internal class InboundGroupSessionStore @Inject constructor(
|
||||||
|
|
||||||
private fun internalStoreGroupSession(holder: InboundGroupSessionHolder, sessionId: String, senderKey: String) {
|
private fun internalStoreGroupSession(holder: InboundGroupSessionHolder, sessionId: String, senderKey: String) {
|
||||||
Timber.tag(loggerTag.value).v("## Inbound: getInboundGroupSession mark as dirty ${holder.wrapper.roomId}-${holder.wrapper.senderKey}")
|
Timber.tag(loggerTag.value).v("## Inbound: getInboundGroupSession mark as dirty ${holder.wrapper.roomId}-${holder.wrapper.senderKey}")
|
||||||
// We want to batch this a bit for performances
|
|
||||||
dirtySession.add(holder)
|
|
||||||
|
|
||||||
if (sessionCache[CacheKey(sessionId, senderKey)] == null) {
|
if (sessionCache[CacheKey(sessionId, senderKey)] == null) {
|
||||||
// first time seen, put it in memory cache while waiting for batch insert
|
// first time seen, put it in memory cache while waiting for batch insert
|
||||||
// If it's already known, no need to update cache it's already there
|
// If it's already known, no need to update cache it's already there
|
||||||
sessionCache.put(CacheKey(sessionId, senderKey), holder)
|
sessionCache.put(CacheKey(sessionId, senderKey), holder)
|
||||||
}
|
}
|
||||||
|
|
||||||
timerTask?.cancel()
|
|
||||||
timerTask = object : TimerTask() {
|
|
||||||
override fun run() {
|
|
||||||
batchSave()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timer.schedule(timerTask!!, 300)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
private fun batchSave() {
|
|
||||||
val toSave = mutableListOf<InboundGroupSessionHolder>().apply { addAll(dirtySession) }
|
|
||||||
dirtySession.clear()
|
|
||||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||||
Timber.tag(loggerTag.value).v("## Inbound: getInboundGroupSession batching save of ${toSave.size}")
|
store.storeInboundGroupSessions(listOf(holder.wrapper))
|
||||||
tryOrNull {
|
|
||||||
store.storeInboundGroupSessions(toSave.map { it.wrapper })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1349,6 +1349,8 @@ internal class DefaultKeysBackupService @Inject constructor(
|
||||||
|
|
||||||
// Mark keys as backed up
|
// Mark keys as backed up
|
||||||
cryptoStore.markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers)
|
cryptoStore.markBackupDoneForInboundGroupSessions(olmInboundGroupSessionWrappers)
|
||||||
|
// we can release the sessions now
|
||||||
|
olmInboundGroupSessionWrappers.onEach { it.session.releaseSession() }
|
||||||
|
|
||||||
if (olmInboundGroupSessionWrappers.size < KEY_BACKUP_SEND_KEYS_MAX_COUNT) {
|
if (olmInboundGroupSessionWrappers.size < KEY_BACKUP_SEND_KEYS_MAX_COUNT) {
|
||||||
Timber.v("backupKeys: All keys have been backed up")
|
Timber.v("backupKeys: All keys have been backed up")
|
||||||
|
|
|
@ -763,11 +763,17 @@ internal class RealmCryptoStore @Inject constructor(
|
||||||
// } ?: false
|
// } ?: false
|
||||||
val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionIdentifier, wrapper.sessionData.senderKey)
|
val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionIdentifier, wrapper.sessionData.senderKey)
|
||||||
|
|
||||||
|
val existing = realm.where<OlmInboundGroupSessionEntity>()
|
||||||
|
.equalTo(OlmInboundGroupSessionEntityFields.PRIMARY_KEY, key)
|
||||||
|
.findFirst()
|
||||||
|
|
||||||
val realmOlmInboundGroupSession = OlmInboundGroupSessionEntity().apply {
|
val realmOlmInboundGroupSession = OlmInboundGroupSessionEntity().apply {
|
||||||
primaryKey = key
|
primaryKey = key
|
||||||
store(wrapper)
|
store(wrapper)
|
||||||
|
backedUp = existing?.backedUp ?: false
|
||||||
}
|
}
|
||||||
Timber.i("## CRYPTO | shouldShareHistory: ${wrapper.sessionData.sharedHistory} for $key")
|
|
||||||
|
Timber.v("## CRYPTO | shouldShareHistory: ${wrapper.sessionData.sharedHistory} for $key")
|
||||||
realm.insertOrUpdate(realmOlmInboundGroupSession)
|
realm.insertOrUpdate(realmOlmInboundGroupSession)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue