IJPL-578 Minimize amount of special handling of the headless mode in FileBasedIndexTumbler

GitOrigin-RevId: 4409c8c9b6001d8276d536f8902bca17fc6eaf13
This commit is contained in:
Andrei.Kuznetsov
2024-01-25 11:49:09 +01:00
committed by intellij-monorepo-bot
parent 0fde1841f9
commit ddeefd7ffd
5 changed files with 30 additions and 19 deletions

View File

@@ -11,6 +11,7 @@ import com.intellij.openapi.fileTypes.FileTypeManager
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.DumbModeTask
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.DumbServiceImpl
import com.intellij.openapi.project.UnindexedFilesScannerExecutor
import com.intellij.openapi.roots.AdditionalLibraryRootsProvider
import com.intellij.openapi.util.Disposer
@@ -36,8 +37,6 @@ class FileBasedIndexTumbler(private val reason: @NonNls String) {
LOG.assertTrue(!app.isWriteAccessAllowed)
try {
if (nestedLevelCount == 0) {
val headless = app.isHeadlessEnvironment
if (!headless) {
val wasUp = dumbModeSemaphore.isUp
dumbModeSemaphore.down()
if (wasUp) {
@@ -55,7 +54,6 @@ class FileBasedIndexTumbler(private val reason: @NonNls String) {
MyDumbModeTask(dumbModeSemaphore).queue(project)
}
}
}
LOG.assertTrue(fileTypeTracker == null)
fileTypeTracker = FileTypeTracker()
@@ -86,18 +84,15 @@ class FileBasedIndexTumbler(private val reason: @NonNls String) {
if (nestedLevelCount == 0) {
try {
fileBasedIndex.loadIndexes()
val headless = ApplicationManager.getApplication().isHeadlessEnvironment
if (headless) {
if (DumbServiceImpl.isSynchronousTaskExecution) {
fileBasedIndex.waitUntilIndicesAreInitialized()
}
if (!headless) {
for (project in ProjectUtil.getOpenProjects()) {
UnindexedFilesScannerExecutor.getInstance(project).resumeQueue(onFinish = {})
project.getService(PerProjectIndexingQueue::class.java).resumeQueue()
FileBasedIndexInfrastructureExtension.attachAllExtensionsData(project)
}
dumbModeSemaphore.up()
for (project in ProjectUtil.getOpenProjects()) {
UnindexedFilesScannerExecutor.getInstance(project).resumeQueue(onFinish = {})
project.getService(PerProjectIndexingQueue::class.java).resumeQueue()
FileBasedIndexInfrastructureExtension.attachAllExtensionsData(project)
}
dumbModeSemaphore.up()
val runRescanning = CorruptionMarker.requireInvalidation() || (Registry.`is`("run.index.rescanning.on.plugin.load.unload") ||
snapshot is FbiSnapshot.RebuildRequired ||
@@ -129,6 +124,9 @@ class FileBasedIndexTumbler(private val reason: @NonNls String) {
private class MyDumbModeTask(val semaphore: Semaphore) : DumbModeTask() {
override fun performInDumbMode(indicator: ProgressIndicator) {
if (DumbServiceImpl.isSynchronousTaskExecution) {
return // TODO: this will be a deadlock otherwise (IJPL-578)
}
indicator.text = IndexingBundle.message("indexes.reloading")
semaphore.waitFor()
}

View File

@@ -398,7 +398,8 @@ open class DumbServiceImpl @NonInjectable @VisibleForTesting constructor(private
// isRunning will be false eventually, because we are on EDT, and no new task can be queued outside the EDT
// (we only wait for currently running task to terminate).
myGuiDumbTaskRunner.cancelAllTasks()
while (myGuiDumbTaskRunner.isRunning.value && !myProject.isDisposed) {
mySyncDumbTaskRunner.cancelAllTasks()
while ((myGuiDumbTaskRunner.isRunning.value || mySyncDumbTaskRunner.isRunning.value) && !myProject.isDisposed) {
PingProgress.interactWithEdtProgress()
LockSupport.parkNanos(50000000)
}
@@ -576,10 +577,11 @@ open class DumbServiceImpl @NonInjectable @VisibleForTesting constructor(private
@TestOnly
suspend fun waitUntilFinished() {
myGuiDumbTaskRunner.waitUntilFinished()
mySyncDumbTaskRunner.isRunning.first { !it }
}
@TestOnly
val isRunning = myGuiDumbTaskRunner.isRunning
val isRunning: Boolean = myGuiDumbTaskRunner.isRunning.value || mySyncDumbTaskRunner.isRunning.value
companion object {
@JvmField

View File

@@ -9,13 +9,14 @@ import com.intellij.openapi.progress.*;
import com.intellij.openapi.progress.impl.CoreProgressManager;
import com.intellij.openapi.project.DumbServiceMergingTaskQueue.QueuedDumbModeTask;
import com.intellij.openapi.util.Disposer;
import kotlinx.coroutines.flow.MutableStateFlow;
import kotlinx.coroutines.flow.StateFlow;
import kotlinx.coroutines.flow.StateFlowKt;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.atomic.AtomicBoolean;
public final class DumbServiceSyncTaskQueue {
private final Project myProject;
private final AtomicBoolean myIsRunning = new AtomicBoolean(false);
private final MutableStateFlow<Boolean> myIsRunning = StateFlowKt.MutableStateFlow(false);
private final DumbServiceMergingTaskQueue myTaskQueue;
public DumbServiceSyncTaskQueue(@NotNull Project project, @NotNull DumbServiceMergingTaskQueue queue) {
@@ -58,7 +59,7 @@ public final class DumbServiceSyncTaskQueue {
}
}
finally {
myIsRunning.set(false);
myIsRunning.setValue(false);
}
};
@@ -71,6 +72,10 @@ public final class DumbServiceSyncTaskQueue {
}
}
public void cancelAllTasks() {
myTaskQueue.cancelAllTasks();
}
public void disposePendingTasks() {
myTaskQueue.disposePendingTasks();
}
@@ -100,4 +105,8 @@ public final class DumbServiceSyncTaskQueue {
}
}, listenerDisposable);
}
public StateFlow<Boolean> isRunning() {
return myIsRunning;
}
}

View File

@@ -145,6 +145,8 @@ open class MergingQueueGuiExecutor<T : MergeableQueueTask<T>> protected construc
startedInBackground = mySingleTaskExecutor.tryStartProcess { task: AutoclosableProgressive ->
try {
// TODO: there seems to be a race between mySingleTaskExecutor.tryStartProcess and FileBasedIndexTumbler. Return now
if (mySuspended.get()) return@tryStartProcess
backgroundTasksSubmitted.incrementAndGet()
startInBackgroundWithVisibleOrInvisibleProgress { visibleOrInvisibleIndicator ->
try {

View File

@@ -98,7 +98,7 @@ class IndexingTestUtil(private val project: Project) {
}
private fun isRunning(): Boolean {
return UnindexedFilesScannerExecutor.getInstance(project).isRunning.value || DumbServiceImpl.getInstance(project).isRunning.value
return UnindexedFilesScannerExecutor.getInstance(project).isRunning.value || DumbServiceImpl.getInstance(project).isRunning
}
suspend fun suspendUntilIndexesAreReady() {