From bd31ae3093ac29ed7f0daba4cd0656f53dcab43b Mon Sep 17 00:00:00 2001 From: Sergey Patrikeev Date: Fri, 19 Feb 2021 01:01:58 +0300 Subject: [PATCH] Indexing diagnostics: ensure all indexing listeners are called on indexing started/finished. This is needed to guarantee that the FUS reporter is called for the "started" and "finished" events. GitOrigin-RevId: bacf9183f6c6530beae22b00c5d66d5904e24d7b --- .../diagnostic/IndexDiagnosticDumper.kt | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/diagnostic/IndexDiagnosticDumper.kt b/platform/lang-impl/src/com/intellij/util/indexing/diagnostic/IndexDiagnosticDumper.kt index 4bc817d2d161..01f9fb6dc996 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/diagnostic/IndexDiagnosticDumper.kt +++ b/platform/lang-impl/src/com/intellij/util/indexing/diagnostic/IndexDiagnosticDumper.kt @@ -8,8 +8,11 @@ import com.intellij.openapi.Disposable import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.PathManager import com.intellij.openapi.components.service +import com.intellij.openapi.diagnostic.ControlFlowException import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.progress.ProcessCanceledException +import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.getProjectCachePath import com.intellij.util.SystemProperties import com.intellij.util.concurrency.NonUrgentExecutor @@ -84,7 +87,7 @@ class IndexDiagnosticDumper : Disposable { } fun onIndexingStarted(projectIndexingHistory: ProjectIndexingHistory) { - ProjectIndexingHistoryListener.EP_NAME.forEachExtensionSafe { it.onStartedIndexing(projectIndexingHistory) } + runAllListenersSafely { onStartedIndexing(projectIndexingHistory) } } fun onIndexingFinished(projectIndexingHistory: ProjectIndexingHistory) { @@ -96,8 +99,26 @@ class IndexDiagnosticDumper : Disposable { return } NonUrgentExecutor.getInstance().execute { dumpProjectIndexingHistoryToLogSubdirectory(projectIndexingHistory) } - } finally { - ProjectIndexingHistoryListener.EP_NAME.forEachExtensionSafe { it.onFinishedIndexing(projectIndexingHistory) } + } + finally { + runAllListenersSafely { onFinishedIndexing(projectIndexingHistory) } + } + } + + private fun runAllListenersSafely(block: ProjectIndexingHistoryListener.() -> Unit) { + val listeners = ProgressManager.getInstance().computeInNonCancelableSection, Exception> { + ProjectIndexingHistoryListener.EP_NAME.extensionList + } + for (listener in listeners) { + try { + listener.block() + } catch (e: Exception) { + if (e is ControlFlowException) { + // Make all listeners run first. + continue + } + LOG.error(e) + } } }