From 39ef262a5afe774ed55fecc42c3d839130a0c210 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Thu, 16 Dec 2021 14:12:53 +0200 Subject: [PATCH 1/2] Added a delay when use MsgsCacheManager.getMsgSnapshot().| #1549 --- .../jetpack/viewmodel/MsgDetailsViewModel.kt | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt index ec2858400f..9453f44747 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt @@ -54,6 +54,7 @@ import com.sun.mail.imap.IMAPBodyPart import com.sun.mail.imap.IMAPFolder import com.sun.mail.imap.IMAPMessage import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -476,8 +477,16 @@ class MsgDetailsViewModel( Result.success(null) } if (result.status == Result.Status.SUCCESS) { - return@withContext MsgsCacheManager.getMsgSnapshot(messageEntity.id.toString()) - ?: throw java.lang.NullPointerException("Message not found in the local cache") + var snapshot = MsgsCacheManager.getMsgSnapshot(messageEntity.id.toString()) + if (snapshot == null) { + //due to realization of [DiskLruCache] we need to do a little delay + // while [DiskLruCache] is updating internal data + delay(500) + snapshot = MsgsCacheManager.getMsgSnapshot(messageEntity.id.toString()) + } + + return@withContext snapshot + ?: throw java.lang.NullPointerException("Message not found in the local cache (GOOGLE API)") } else throw result.exception ?: java.lang.IllegalStateException( context.getString( R @@ -553,8 +562,16 @@ class MsgDetailsViewModel( ) ) - return@execute MsgsCacheManager.getMsgSnapshot(messageEntity.id.toString()) - ?: throw java.lang.NullPointerException("Message not found in the local cache") + var snapshot = MsgsCacheManager.getMsgSnapshot(messageEntity.id.toString()) + if (snapshot == null) { + //due to realization of [DiskLruCache] we need to do a little delay + // while [DiskLruCache] is updating internal data + delay(500) + snapshot = MsgsCacheManager.getMsgSnapshot(messageEntity.id.toString()) + } + + return@execute snapshot + ?: throw java.lang.NullPointerException("Message not found in the local cache(IMAP)") } } } From a592bbfec6a4dbe30bf640fd35dd66cdc7e5cfdc Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Fri, 17 Dec 2021 10:19:05 +0200 Subject: [PATCH 2/2] Added MsgsCacheManager.getMsgSnapshotWithRetryStrategy(). Refactored code.| #1549 --- .../email/api/email/MsgsCacheManager.kt | 17 +++++++++++++++ .../jetpack/viewmodel/MsgDetailsViewModel.kt | 21 ++++--------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/MsgsCacheManager.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/MsgsCacheManager.kt index 04f0f5c9d4..ef3ea3da45 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/MsgsCacheManager.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/MsgsCacheManager.kt @@ -13,6 +13,9 @@ import com.flowcrypt.email.BuildConfig import com.flowcrypt.email.security.KeyStoreCryptoManager import com.flowcrypt.email.util.ProgressOutputStream import com.flowcrypt.email.util.cache.DiskLruCache +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.withContext import okhttp3.internal.io.FileSystem import okio.buffer import java.io.File @@ -69,6 +72,20 @@ object MsgsCacheManager { return diskLruCache[key] } + /** + * Due to the realization of [DiskLruCache] we need to add a little delay + * before fetching [DiskLruCache.Snapshot] + */ + suspend fun getMsgSnapshotWithRetryStrategy(key: String): DiskLruCache.Snapshot? = + withContext(Dispatchers.IO) { + var attemptsCount = 0 + while (diskLruCache[key] == null && attemptsCount <= 50) { + delay(50) + attemptsCount++ + } + return@withContext diskLruCache[key] + } + fun isMsgExist(key: String): Boolean { val snapshot = diskLruCache[key] ?: return false return snapshot.getLength(0) > 0 diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt index 9453f44747..6bb902d1d8 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt @@ -54,7 +54,6 @@ import com.sun.mail.imap.IMAPBodyPart import com.sun.mail.imap.IMAPFolder import com.sun.mail.imap.IMAPMessage import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -477,14 +476,8 @@ class MsgDetailsViewModel( Result.success(null) } if (result.status == Result.Status.SUCCESS) { - var snapshot = MsgsCacheManager.getMsgSnapshot(messageEntity.id.toString()) - if (snapshot == null) { - //due to realization of [DiskLruCache] we need to do a little delay - // while [DiskLruCache] is updating internal data - delay(500) - snapshot = MsgsCacheManager.getMsgSnapshot(messageEntity.id.toString()) - } - + val snapshot = + MsgsCacheManager.getMsgSnapshotWithRetryStrategy(messageEntity.id.toString()) return@withContext snapshot ?: throw java.lang.NullPointerException("Message not found in the local cache (GOOGLE API)") } else throw result.exception ?: java.lang.IllegalStateException( @@ -562,14 +555,8 @@ class MsgDetailsViewModel( ) ) - var snapshot = MsgsCacheManager.getMsgSnapshot(messageEntity.id.toString()) - if (snapshot == null) { - //due to realization of [DiskLruCache] we need to do a little delay - // while [DiskLruCache] is updating internal data - delay(500) - snapshot = MsgsCacheManager.getMsgSnapshot(messageEntity.id.toString()) - } - + val snapshot = + MsgsCacheManager.getMsgSnapshotWithRetryStrategy(messageEntity.id.toString()) return@execute snapshot ?: throw java.lang.NullPointerException("Message not found in the local cache(IMAP)") }