⚡ 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:
M57 authored and GitHub committed 2026-08-04 19:43:32 +03:00
1 parent e52a9c2fe6
commit e1a04a9396
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()