IJPL-149878 IJent WSL FS refactoring: don't initialize IJent in every WSL during IjentWslNioFsToggler initialization

Instead, the file systems are assigned to WSL distribution explicitly by calling `enableForAllWslDistributions`.

This change removes a race condition between FS enabling/disabling in the benchmark tests.

GitOrigin-RevId: 9c06b1f713068f061fdb8c09080c3c9a81aeee15
This commit is contained in:
Vladimir Lagunov
2024-06-27 14:20:27 +02:00
committed by intellij-monorepo-bot
parent 3d9dc83f8e
commit 1eacd1d1af
4 changed files with 19 additions and 14 deletions

View File

@@ -17,11 +17,15 @@ import kotlinx.coroutines.launch
/** Starts the IJent if a project on WSL is opened. */
internal class IjentInProjectStarter : ProjectActivity {
override suspend fun execute(project: Project): Unit = coroutineScope {
val service = serviceAsync<IjentWslNioFsToggler>()
if (!service.isInitialized) {
val ijentWslNioFsToggler = IjentWslNioFsToggler.instanceAsync()
if (!ijentWslNioFsToggler.isAvailable) {
return@coroutineScope
}
launch {
ijentWslNioFsToggler.enableForAllWslDistributions()
}
val allWslDistributions = async(Dispatchers.IO) {
serviceAsync<WslDistributionManager>().installedDistributions
}

View File

@@ -11,6 +11,7 @@ import com.intellij.platform.ijent.community.impl.nio.IjentNioFileSystemProvider
import com.intellij.platform.ijent.community.impl.nio.telemetry.TracingFileSystemProvider
import com.intellij.util.containers.forEachGuaranteed
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.job
import kotlinx.coroutines.launch
import java.net.URI
@@ -26,13 +27,13 @@ internal class IjentWslNioFsToggleStrategy(
) {
private val ownFileSystems = OwnFileSystems(multiRoutingFileSystemProvider)
val isInitialized: Boolean = true
fun initialize() {
init {
coroutineScope.coroutineContext.job.invokeOnCompletion {
ownFileSystems.unregisterAll()
}
}
suspend fun enableForAllWslDistributions() {
val listener = BiConsumer<Set<WSLDistribution>, Set<WSLDistribution>> { old, new ->
// TODO The code is race prone. Frequent creations and deletions of WSL containers may break the state.
for (distro in new - old) {
@@ -51,8 +52,7 @@ internal class IjentWslNioFsToggleStrategy(
wslDistributionManager.removeWslDistributionsChangeListener(listener)
}
// The function may be called under a read lock, so it's better to postpone the execution.
coroutineScope.launch {
coroutineScope {
for (distro in wslDistributionManager.installedDistributions) {
launch {
handleWslDistributionAddition(distro)

View File

@@ -36,6 +36,13 @@ class IjentWslNioFsToggler(private val coroutineScope: CoroutineScope) {
}
}
val isAvailable: Boolean get() = strategy != null
suspend fun enableForAllWslDistributions() {
strategy ?: error("Not available")
strategy.enableForAllWslDistributions()
}
fun enable(distro: WSLDistribution, ijentId: IjentId) {
strategy?.enable(distro, ijentId)
}
@@ -63,12 +70,6 @@ class IjentWslNioFsToggler(private val coroutineScope: CoroutineScope) {
}
}
init {
strategy?.initialize()
}
val isInitialized: Boolean get() = strategy?.isInitialized ?: false
@TestOnly
fun unregisterAll() {
coroutineScope.cancel()

View File

@@ -140,7 +140,7 @@ object IjentWslNioFsVmOptionsSetter {
val changedOptions = ensureInVmOptions()
when {
changedOptions.isEmpty() -> {
IjentWslNioFsToggler.instanceAsync() // Implicitly activates IJent FS for all WSL distributions.
IjentWslNioFsToggler.instanceAsync().enableForAllWslDistributions()
}
PluginManagerCore.isRunningFromSources() || AppMode.isDevServer() ->