From 026a563625c53edc27feede594c1938cdd43446c Mon Sep 17 00:00:00 2001 From: Vladimir Lagunov Date: Thu, 27 Jun 2024 14:05:45 +0200 Subject: [PATCH] IJPL-149878 IJent WSL FS refactoring: hide coroutine scope of `IjentWslNioFsToggler` As a consequence, `IjentInProjectStarted.execute` suspends the calling coroutine until all IJent server-side applications start. It also looks fairer because starting IJents is required for project initialization. GitOrigin-RevId: ea7914aced38c3ece0ab8a59e8bde8b51ccd47ce --- .../ijent/nio/toggle/IjentInProjectStarter.kt | 17 +++++++++-------- .../ijent/nio/toggle/IjentWslNioFsToggler.kt | 9 ++++++++- .../nio/toggle/IjentWslNioFsVmOptionsSetter.kt | 12 +++++++++--- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentInProjectStarter.kt b/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentInProjectStarter.kt index 3463f504b761..13656a39b311 100644 --- a/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentInProjectStarter.kt +++ b/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentInProjectStarter.kt @@ -9,20 +9,21 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.project.modules import com.intellij.openapi.project.rootManager import com.intellij.openapi.startup.ProjectActivity -import kotlinx.coroutines.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch /** Starts the IJent if a project on WSL is opened. */ internal class IjentInProjectStarter : ProjectActivity { - override suspend fun execute(project: Project) { + override suspend fun execute(project: Project): Unit = coroutineScope { val service = serviceAsync() if (!service.isInitialized) { - return + return@coroutineScope } - val allWslDistributions = service.coroutineScope.async { - withContext(Dispatchers.IO) { - serviceAsync().installedDistributions - } + val allWslDistributions = async(Dispatchers.IO) { + serviceAsync().installedDistributions } val relatedWslDistributions = hashSetOf() @@ -53,7 +54,7 @@ internal class IjentInProjectStarter : ProjectActivity { } for (distro in relatedWslDistributions) { - service.coroutineScope.launch { + launch { serviceAsync().getIjentApi(distro, project, false) } } diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentWslNioFsToggler.kt b/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentWslNioFsToggler.kt index fc49742338a8..3d0c63fa07b1 100644 --- a/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentWslNioFsToggler.kt +++ b/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentWslNioFsToggler.kt @@ -12,7 +12,9 @@ import com.intellij.openapi.util.SystemInfo import com.intellij.platform.core.nio.fs.MultiRoutingFileSystemProvider import com.intellij.platform.ijent.IjentId import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.cancel import org.jetbrains.annotations.ApiStatus.Internal +import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.VisibleForTesting import java.nio.file.FileSystems @@ -22,7 +24,7 @@ import java.nio.file.FileSystems @Internal @Service @VisibleForTesting -class IjentWslNioFsToggler(@VisibleForTesting val coroutineScope: CoroutineScope) { // TODO Try to hide coroutineScope +class IjentWslNioFsToggler(private val coroutineScope: CoroutineScope) { companion object { suspend fun instanceAsync(): IjentWslNioFsToggler = serviceAsync() fun instance(): IjentWslNioFsToggler = service() @@ -66,4 +68,9 @@ class IjentWslNioFsToggler(@VisibleForTesting val coroutineScope: CoroutineScope } val isInitialized: Boolean get() = strategy?.isInitialized ?: false + + @TestOnly + fun unregisterAll() { + coroutineScope.cancel() + } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentWslNioFsVmOptionsSetter.kt b/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentWslNioFsVmOptionsSetter.kt index 3b4c6598f445..3ee4f3d70e91 100644 --- a/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentWslNioFsVmOptionsSetter.kt +++ b/platform/platform-impl/src/com/intellij/execution/wsl/ijent/nio/toggle/IjentWslNioFsVmOptionsSetter.kt @@ -9,6 +9,7 @@ import com.intellij.ide.plugins.PluginManagerCore import com.intellij.idea.AppMode import com.intellij.openapi.application.* import com.intellij.openapi.application.ex.ApplicationManagerEx +import com.intellij.openapi.components.Service import com.intellij.openapi.components.service import com.intellij.openapi.ui.Messages import com.intellij.openapi.wm.IdeFrame @@ -17,6 +18,7 @@ import com.intellij.platform.core.nio.fs.MultiRoutingFileSystemProvider import com.intellij.platform.ijent.community.buildConstants.IJENT_BOOT_CLASSPATH_MODULE import com.intellij.platform.ijent.community.buildConstants.IJENT_WSL_FILE_SYSTEM_REGISTRY_KEY import com.intellij.platform.ijent.community.buildConstants.isIjentWslFsEnabledByDefaultForProduct +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.jetbrains.annotations.VisibleForTesting @@ -132,12 +134,16 @@ class IjentWslNioFsVmOptionsSetter : ApplicationActivationListener { } } + @Service + private class ServiceScope(coroutineScope: CoroutineScope) : CoroutineScope by coroutineScope + override fun applicationActivated(ideFrame: IdeFrame) { - val service = service() - service.coroutineScope.launch { + service().launch { val changedOptions = ensureInVmOptions() when { - changedOptions.isEmpty() -> Unit + changedOptions.isEmpty() -> { + IjentWslNioFsToggler.instanceAsync() // Implicitly activates IJent FS for all WSL distributions. + } PluginManagerCore.isRunningFromSources() || AppMode.isDevServer() -> launch(Dispatchers.EDT + ModalityState.nonModal().asContextElement()) {