[platform-eel] IJPL-194035: All IJent filesystems are loaded greedily by recent projects in Welcome Screen

(cherry picked from commit 7868f0266f728dbbca0666c600e5964a1d4282e5)


(cherry picked from commit 4d3ec53a85d91ddb66a547edfea28c39157cb4c5)

IJ-MR-167682

GitOrigin-RevId: 96b3ebfbcfe9642a6010fd9b7726ca17742ac03d
This commit is contained in:
Andrii Zinchenko
2025-06-26 16:53:23 +02:00
committed by intellij-monorepo-bot
parent 9a0da96e42
commit bde25e49ad
5 changed files with 41 additions and 16 deletions

View File

@@ -38,15 +38,15 @@ import java.util.concurrent.atomic.AtomicReference
@Suppress("FunctionName")
fun IjentFailSafeFileSystemPosixApi(
coroutineScope: CoroutineScope,
delegateFactory: suspend () -> IjentPosixApi,
descriptor: EelDescriptor,
): IjentFileSystemApi {
val holder = DelegateHolder<IjentPosixApi, IjentFileSystemPosixApi>(coroutineScope, delegateFactory)
return IjentFailSafeFileSystemPosixApiImpl(holder)
val holder = DelegateHolder<IjentPosixApi, IjentFileSystemPosixApi>(coroutineScope, descriptor)
return IjentFailSafeFileSystemPosixApiImpl(holder, descriptor)
}
private class DelegateHolder<I : IjentApi, F : IjentFileSystemApi>(
private val coroutineScope: CoroutineScope,
private val delegateFactory: suspend () -> I,
private val descriptor: EelDescriptor
) {
private val delegate = AtomicReference<Deferred<I>?>(null)
@@ -63,7 +63,8 @@ private class DelegateHolder<I : IjentApi, F : IjentFileSystemApi>(
oldDelegate
else
coroutineScope.async(Dispatchers.IO, start = CoroutineStart.LAZY) {
delegateFactory()
@Suppress("UNCHECKED_CAST")
descriptor.toEelApi() as I
}
}!!
@@ -100,6 +101,7 @@ private class DelegateHolder<I : IjentApi, F : IjentFileSystemApi>(
*/
private class IjentFailSafeFileSystemPosixApiImpl(
private val holder: DelegateHolder<IjentPosixApi, IjentFileSystemPosixApi>,
override val descriptor: EelDescriptor
) : IjentFileSystemPosixApi {
// TODO Make user suspendable again?
override val user: EelUserPosixInfo by lazy {
@@ -108,13 +110,6 @@ private class IjentFailSafeFileSystemPosixApiImpl(
}
}
override val descriptor: EelDescriptor by lazy {
runBlocking {
holder.withDelegateRetrying { descriptor }
}
}
override suspend fun listDirectory(
path: EelPath,
): EelResult<Collection<String>, EelFileSystemApi.ListDirectoryError> =

View File

@@ -3,7 +3,6 @@ package com.intellij.platform.ide.impl.wsl.ijent.nio.toggle
import com.intellij.execution.wsl.WSLDistribution
import com.intellij.execution.wsl.WslDistributionManager
import com.intellij.execution.wsl.WslIjentManager
import com.intellij.openapi.diagnostic.logger
import com.intellij.platform.eel.provider.EelNioBridgeService
import com.intellij.platform.ide.impl.wsl.ijent.nio.IjentWslNioFileSystemProvider
@@ -74,9 +73,8 @@ class IjentWslNioFsToggleStrategy(
fun switchToIjentFs(distro: WSLDistribution) {
val ijentFsProvider = TracingFileSystemProvider(IjentNioFileSystemProvider.getInstance())
try {
val ijentFs = IjentFailSafeFileSystemPosixApi(coroutineScope) {
WslIjentManager.instanceAsync().getIjentApi(distro, null, false)
}
val distributionId = distro.id
val ijentFs = IjentFailSafeFileSystemPosixApi(coroutineScope, WslEelDescriptor(WSLDistribution(distributionId)))
ijentFsProvider.newFileSystem(
URI("ijent", "wsl", "/${distro.id}", null, null),
IjentNioFileSystemProvider.newFileSystemMap(ijentFs),

View File

@@ -7,6 +7,8 @@ import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectStorePathManager
import com.intellij.openapi.util.registry.Registry
import com.intellij.platform.eel.provider.LocalEelDescriptor
import com.intellij.platform.eel.provider.getEelDescriptor
import com.intellij.ui.IconDeferrer
import com.intellij.ui.JBColor
import com.intellij.ui.LayeredIcon
@@ -34,6 +36,7 @@ import java.nio.file.attribute.BasicFileAttributes
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
import javax.swing.Icon
import kotlin.io.path.Path
@Internal
fun unscaledProjectIconSize(): Int = Registry.intValue("ide.project.icon.size", 20)
@@ -216,6 +219,14 @@ private fun getCustomIconFileInfo(path: @SystemIndependent String): Pair<Path, B
}
private fun getCustomIcon(path: @SystemIndependent String, isProjectValid: Boolean, iconSize: Int): Icon? {
// IJPL-194035
// Avoid greedy I/O under non-local projects. For example, in the case of WSL:
// 1. it may trigger Ijent initialization for each recent project
// 2. with Ijent disabled, performance may degrade further — 9P is very slow and could lead to UI freezes
if (Path(path).getEelDescriptor() != LocalEelDescriptor) {
return null
}
val (file, fileInfo) = getCustomIconFileInfo(path) ?: return null
val timestamp = fileInfo.lastModifiedTime().toMillis()

View File

@@ -43,6 +43,8 @@ import com.intellij.openapi.wm.impl.*
import com.intellij.openapi.wm.impl.customFrameDecorations.header.CustomWindowHeaderUtil
import com.intellij.platform.diagnostic.telemetry.impl.span
import com.intellij.platform.eel.provider.EelInitialization
import com.intellij.platform.eel.provider.LocalEelDescriptor
import com.intellij.platform.eel.provider.getEelDescriptor
import com.intellij.platform.ide.diagnostic.startUpPerformanceReporter.FUSProjectHotStartUpMeasurer
import com.intellij.project.stateStore
import com.intellij.ui.mac.createMacDelegate
@@ -71,6 +73,7 @@ import java.util.concurrent.atomic.LongAdder
import javax.swing.Icon
import javax.swing.JFrame
import kotlin.collections.Map.Entry
import kotlin.io.path.Path
import kotlin.io.path.exists
import kotlin.io.path.invariantSeparatorsPathString
import kotlin.io.path.relativeTo
@@ -953,6 +956,14 @@ private fun readProjectName(path: String): String {
return path
}
// IJPL-194035
// Avoid greedy I/O under non-local projects. For example, in the case of WSL:
// 1. it may trigger Ijent initialization for each recent project
// 2. with Ijent disabled, performance may degrade further — 9P is very slow and could lead to UI freezes
if (Path(path).getEelDescriptor() != LocalEelDescriptor) {
return path
}
if (path.endsWith(".ipr")) {
return FileUtilRt.getNameWithoutExtension(path)
}

View File

@@ -13,6 +13,8 @@ import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.options.advanced.AdvancedSettings
import com.intellij.openapi.wm.IdeFrame
import com.intellij.platform.eel.provider.LocalEelDescriptor
import com.intellij.platform.eel.provider.getEelDescriptor
import com.intellij.util.application
import git4idea.GitUtil
import git4idea.branch.GitBranchUtil
@@ -93,6 +95,14 @@ internal class GitRecentProjectsBranchesService(val coroutineScope: CoroutineSco
if (!showBranchMode.shouldShow(nameIsDistinct)) {
return null
}
// IJPL-194035
// Avoid greedy I/O under non-local projects. For example, in the case of WSL:
// 1. it may trigger Ijent initialization for each recent project
// 2. with Ijent disabled, performance may degrade further — 9P is very slow and could lead to UI freezes
if (Path(projectPath).getEelDescriptor() != LocalEelDescriptor) {
return null
}
val branchFuture = cache.get(projectPath)
return (branchFuture.getNow(GitRecentProjectCachedBranch.Unknown) as? GitRecentProjectCachedBranch.KnownBranch)?.branchName
}