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
This commit is contained in:
Vladimir Lagunov
2024-06-27 14:05:45 +02:00
committed by intellij-monorepo-bot
parent 5ce0d4c891
commit 026a563625
3 changed files with 26 additions and 12 deletions

View File

@@ -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<IjentWslNioFsToggler>()
if (!service.isInitialized) {
return
return@coroutineScope
}
val allWslDistributions = service.coroutineScope.async {
withContext(Dispatchers.IO) {
serviceAsync<WslDistributionManager>().installedDistributions
}
val allWslDistributions = async(Dispatchers.IO) {
serviceAsync<WslDistributionManager>().installedDistributions
}
val relatedWslDistributions = hashSetOf<WSLDistribution>()
@@ -53,7 +54,7 @@ internal class IjentInProjectStarter : ProjectActivity {
}
for (distro in relatedWslDistributions) {
service.coroutineScope.launch {
launch {
serviceAsync<WslIjentManager>().getIjentApi(distro, project, false)
}
}

View File

@@ -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()
}
}

View File

@@ -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<IjentWslNioFsToggler>()
service.coroutineScope.launch {
service<ServiceScope>().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()) {