⚡ Optimize PersistentCookieJar by removing runBlocking (#799)
* perf: remove runBlocking from PersistentCookieJar to fix overhead * perf: remove runBlocking from PersistentCookieJar to fix overhead * perf: fix PersistentCookieJar race condition using CountDownLatch * perf: remove runBlocking from PersistentCookieJar to fix overhead
This commit is contained in:
4 files changed
+69
-13
No files matched your search
@@ -130,7 +130,7 @@ object AuthManager {
|
||||
_useDynamicColorsFlow.value = state.useDynamicColors
|
||||
_themePresetFlow.value = state.themePreset
|
||||
// B7 (Jul 08 2026, kanban t_470): keep cookie scope aligned with active profile.
|
||||
syncCookieStoreForProfile(state.selectedProfileId)
|
||||
appScope?.launch { syncCookieStoreForProfile(state.selectedProfileId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -332,13 +332,13 @@ object AuthManager {
|
||||
}
|
||||
_tokenFlow.value = getToken()
|
||||
// B7 (Jul 08 2026, kanban t_470): keep cookie scope aligned with active profile.
|
||||
syncCookieStoreForProfile(id)
|
||||
appScope?.launch { syncCookieStoreForProfile(id) }
|
||||
}
|
||||
|
||||
private fun normalizedProfileId(profileId: String?): String =
|
||||
profileId?.takeIf { it.isNotBlank() } ?: DEFAULT_PROFILE_ID
|
||||
|
||||
private fun syncCookieStoreForProfile(profileId: String?) {
|
||||
private suspend fun syncCookieStoreForProfile(profileId: String?) {
|
||||
if (!CookieManager.isInitialized()) return
|
||||
val normalizedId = normalizedProfileId(profileId)
|
||||
if (CookieManager.cookieJar.currentServer() != normalizedId) {
|
||||
|
||||
@@ -7,7 +7,6 @@ import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.Cookie
|
||||
|
||||
/**
|
||||
@@ -52,9 +51,9 @@ object CookieManager {
|
||||
}
|
||||
|
||||
/** Switch the active server scope and load its persisted cookies. */
|
||||
fun useStore(serverId: String) {
|
||||
suspend fun useStore(serverId: String) {
|
||||
val j = jar ?: return
|
||||
runBlocking(scope.coroutineContext) { j.useStore(serverId) }
|
||||
j.useStore(serverId)
|
||||
}
|
||||
|
||||
/** Read the current dashboard access-cookie value (or null). */
|
||||
|
||||
@@ -10,6 +10,7 @@ import okhttp3.Cookie
|
||||
import okhttp3.CookieJar
|
||||
import okhttp3.HttpUrl
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
/**
|
||||
@@ -38,6 +39,7 @@ class PersistentCookieJar(
|
||||
// serverId -> (host -> cookies)
|
||||
private val cache = ConcurrentHashMap<String, MutableMap<String, MutableList<Cookie>>>()
|
||||
private val loadedScopes = ConcurrentHashMap.newKeySet<String>()
|
||||
private val loadLatches = ConcurrentHashMap<String, CountDownLatch>()
|
||||
|
||||
@Volatile private var currentServerId = AtomicReference(initialServerId)
|
||||
|
||||
@@ -61,9 +63,6 @@ class PersistentCookieJar(
|
||||
*/
|
||||
fun getCookie(name: String): Cookie? {
|
||||
val serverId = currentServerId.get()
|
||||
if (!loadedScopes.contains(serverId)) {
|
||||
kotlinx.coroutines.runBlocking { ensureLoaded(serverId) }
|
||||
}
|
||||
val hosts = cache[serverId] ?: return null
|
||||
for (bucket in hosts.values) {
|
||||
synchronized(bucket) {
|
||||
@@ -106,10 +105,6 @@ class PersistentCookieJar(
|
||||
|
||||
override fun loadForRequest(url: HttpUrl): List<Cookie> {
|
||||
val serverId = currentServerId.get()
|
||||
// Best-effort synchronous load on first touch (tests/first call).
|
||||
if (!loadedScopes.contains(serverId)) {
|
||||
kotlinx.coroutines.runBlocking { ensureLoaded(serverId) }
|
||||
}
|
||||
val hostKey = url.host
|
||||
val hosts = cache[serverId] ?: return emptyList()
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
Reference in new issue
Block a user