mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-345401 Report cancellation reason of health checks
GitOrigin-RevId: e16029e99152fd5f680a9069626de271afcbb60b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9606d15f40
commit
c8fbf968b9
+6
-2
@@ -11,7 +11,7 @@ import com.intellij.openapi.project.Project
|
||||
*/
|
||||
internal object IndexableFilesFilterHealthCheckCollector : CounterUsagesCollector() {
|
||||
private val GROUP = EventLogGroup("indexable.files.filter",
|
||||
8,
|
||||
9,
|
||||
"FUS",
|
||||
"Collects statistics of ProjectIndexableFilesFilterHealthCheck. " +
|
||||
"See more here: https://youtrack.jetbrains.com/articles/IJPL-A-300/indexable.files.filter")
|
||||
@@ -23,6 +23,7 @@ internal object IndexableFilesFilterHealthCheckCollector : CounterUsagesCollecto
|
||||
private val successfulAttemptNumberInProjectField = EventFields.Int("successful_attempt_number_in_project", "Finished (not-cancelled) health check attempt number in a given project. First is 1.")
|
||||
private val durationMsFiled = EventFields.Int("duration_ms", "Health check duration in milliseconds")
|
||||
private val cancelledAttemptNumberInProjectField = EventFields.Int("cancelled_attempt_number_in_project", "Cancelled health check attempt number in a given project. First is 1.")
|
||||
private val cancellationReasonField = EventFields.Enum("cancellation_reason", FilterActionCancellationReason::class.java)
|
||||
private val nonIndexableFilesInFilterField = EventFields.Int("non_indexable_files_in_filter_count")
|
||||
private val indexableFilesNotInFilterField = EventFields.Int("indexable_files_not_in_filter_count")
|
||||
|
||||
@@ -51,6 +52,7 @@ internal object IndexableFilesFilterHealthCheckCollector : CounterUsagesCollecto
|
||||
attemptNumberInProjectField,
|
||||
cancelledAttemptNumberInProjectField,
|
||||
durationMsFiled,
|
||||
cancellationReasonField,
|
||||
)
|
||||
|
||||
fun reportIndexableFilesFilterHealthcheckStarted(project: Project,
|
||||
@@ -86,13 +88,15 @@ internal object IndexableFilesFilterHealthCheckCollector : CounterUsagesCollecto
|
||||
filter: ProjectIndexableFilesFilter,
|
||||
attemptNumber: Int,
|
||||
cancelledAttemptNumber: Int,
|
||||
durationMs: Int) {
|
||||
durationMs: Int,
|
||||
cancellationReason: FilterActionCancellationReason) {
|
||||
indexableFilesFilterHealthCheckCancelled.log(
|
||||
project,
|
||||
filterNameField.with(getFilterName(filter)),
|
||||
attemptNumberInProjectField.with(attemptNumber),
|
||||
cancelledAttemptNumberInProjectField.with(cancelledAttemptNumber),
|
||||
durationMsFiled.with(durationMs),
|
||||
cancellationReasonField.with(cancellationReason)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+24
-7
@@ -4,6 +4,8 @@ package com.intellij.util.indexing.projectFilter
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.indexing.IdFilter
|
||||
import com.intellij.util.indexing.dependencies.ProjectIndexingDependenciesService
|
||||
import com.intellij.util.indexing.projectFilter.FilterActionCancellationReason.FILTER_IS_UPDATED
|
||||
import com.intellij.util.indexing.projectFilter.FilterActionCancellationReason.SCANNING_IS_IN_PROGRESS
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
internal abstract class ProjectIndexableFilesFilterFactory {
|
||||
@@ -35,18 +37,29 @@ internal abstract class ProjectIndexableFilesFilter(protected val project: Proje
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> runAndCheckThatNoChangesHappened(action: () -> T): T? {
|
||||
fun <T> runAndCheckThatNoChangesHappened(action: () -> T): T {
|
||||
val (numberOfParallelUpdates, version) = parallelUpdatesCounter.getCounterAndVersion()
|
||||
if (numberOfParallelUpdates != 0) return null
|
||||
if (numberOfParallelUpdates != 0) {
|
||||
throw FilterActionCancelledException(FILTER_IS_UPDATED)
|
||||
}
|
||||
val res = action()
|
||||
val (numberOfParallelUpdates2, version2) = parallelUpdatesCounter.getCounterAndVersion()
|
||||
return if (numberOfParallelUpdates2 != 0 || version2 != version) null
|
||||
return if (numberOfParallelUpdates2 != 0 || version2 != version) {
|
||||
throw FilterActionCancelledException(FILTER_IS_UPDATED)
|
||||
}
|
||||
else res
|
||||
}
|
||||
|
||||
abstract fun getFileStatuses(): Sequence<Pair<Int, Boolean>>
|
||||
}
|
||||
|
||||
internal class FilterActionCancelledException(val reason: FilterActionCancellationReason) : Exception()
|
||||
|
||||
internal enum class FilterActionCancellationReason {
|
||||
FILTER_IS_UPDATED,
|
||||
SCANNING_IS_IN_PROGRESS
|
||||
}
|
||||
|
||||
private class AtomicVersionedCounter {
|
||||
private val counterAndVersion = AtomicReference(0 to 0)
|
||||
|
||||
@@ -60,10 +73,14 @@ private class AtomicVersionedCounter {
|
||||
fun getCounterAndVersion(): Pair<Int, Int> = counterAndVersion.get()
|
||||
}
|
||||
|
||||
internal fun <T> runIfScanningScanningIsCompleted(project: Project, action: () -> T): T? {
|
||||
internal fun <T> runIfScanningScanningIsCompleted(project: Project, action: () -> T): T {
|
||||
val service = project.getService(ProjectIndexingDependenciesService::class.java)
|
||||
if (!service.isScanningCompleted()) return null
|
||||
if (!service.isScanningCompleted()) {
|
||||
throw FilterActionCancelledException(SCANNING_IS_IN_PROGRESS)
|
||||
}
|
||||
val res = action()
|
||||
return if (service.isScanningCompleted()) res
|
||||
else null
|
||||
if (!service.isScanningCompleted()) {
|
||||
throw FilterActionCancelledException(SCANNING_IS_IN_PROGRESS)
|
||||
}
|
||||
return res
|
||||
}
|
||||
+44
-32
@@ -100,34 +100,41 @@ class ProjectIndexableFilesFilterHealthCheck(private val project: Project, priva
|
||||
val startTime = System.currentTimeMillis()
|
||||
|
||||
Observation.awaitConfiguration(project) // wait for project import IDEA-348501
|
||||
val res = smartReadAction(project) {
|
||||
runHealthCheck(project, filter)
|
||||
val res: HealthCheckResult = smartReadAction(project) {
|
||||
try {
|
||||
runHealthCheck(project, filter)
|
||||
}
|
||||
catch (e: FilterActionCancelledException) {
|
||||
HealthCheckCancelled(e.reason)
|
||||
}
|
||||
}
|
||||
if (res == null) {
|
||||
IndexableFilesFilterHealthCheckCollector.reportIndexableFilesFilterHealthcheckCancelled(
|
||||
project,
|
||||
filter,
|
||||
attemptNumber,
|
||||
cancelledAttemptsCount.incrementAndGet(),
|
||||
(System.currentTimeMillis() - startTime).toInt())
|
||||
return
|
||||
when (res) {
|
||||
is HealthCheckFinished -> {
|
||||
res.nonIndexableFilesInFilter.fix(filter)
|
||||
res.indexableFilesNotInFilter.fix(filter)
|
||||
|
||||
IndexableFilesFilterHealthCheckCollector.reportIndexableFilesFilterHealthcheck(
|
||||
project,
|
||||
filter,
|
||||
attemptNumber,
|
||||
successfulAttemptsCount.incrementAndGet(),
|
||||
(System.currentTimeMillis() - startTime).toInt(),
|
||||
res.nonIndexableFilesInFilter.size,
|
||||
res.indexableFilesNotInFilter.size)
|
||||
|
||||
res.nonIndexableFilesInFilter.logMessage()
|
||||
res.indexableFilesNotInFilter.logMessage()
|
||||
}
|
||||
is HealthCheckCancelled -> {
|
||||
IndexableFilesFilterHealthCheckCollector.reportIndexableFilesFilterHealthcheckCancelled(
|
||||
project,
|
||||
filter,
|
||||
attemptNumber,
|
||||
cancelledAttemptsCount.incrementAndGet(),
|
||||
(System.currentTimeMillis() - startTime).toInt(),
|
||||
res.reason)
|
||||
}
|
||||
}
|
||||
val (nonIndexableFilesInFilter, indexableFilesNotInFilter) = res
|
||||
|
||||
nonIndexableFilesInFilter.fix(filter)
|
||||
indexableFilesNotInFilter.fix(filter)
|
||||
|
||||
IndexableFilesFilterHealthCheckCollector.reportIndexableFilesFilterHealthcheck(
|
||||
project,
|
||||
filter,
|
||||
attemptNumber,
|
||||
successfulAttemptsCount.incrementAndGet(),
|
||||
(System.currentTimeMillis() - startTime).toInt(),
|
||||
nonIndexableFilesInFilter.size,
|
||||
indexableFilesNotInFilter.size)
|
||||
|
||||
nonIndexableFilesInFilter.logMessage()
|
||||
indexableFilesNotInFilter.logMessage()
|
||||
}
|
||||
catch (_: ProcessCanceledException) {
|
||||
|
||||
@@ -137,9 +144,9 @@ class ProjectIndexableFilesFilterHealthCheck(private val project: Project, priva
|
||||
}
|
||||
}
|
||||
|
||||
private fun runHealthCheck(project: Project, filter: ProjectIndexableFilesFilter): Pair<NonIndexableFilesInFilterGroup, IndexableFilesNotInFilterGroup>? {
|
||||
return runIfScanningScanningIsCompleted(project) {
|
||||
filter.runAndCheckThatNoChangesHappened {
|
||||
private fun runHealthCheck(project: Project, filter: ProjectIndexableFilesFilter): HealthCheckResult {
|
||||
return filter.runAndCheckThatNoChangesHappened {
|
||||
runIfScanningScanningIsCompleted(project) {
|
||||
// It is possible that scanning will start and finish while we are performing healthcheck,
|
||||
// but then healthcheck will be terminated by the fact that filter was update.
|
||||
// If it was not updated, then we don't care that scanning happened, and we can trust healthcheck result
|
||||
@@ -159,7 +166,7 @@ class ProjectIndexableFilesFilterHealthCheck(private val project: Project, priva
|
||||
*/
|
||||
private fun doRunHealthCheck(project: Project,
|
||||
checkAllExpectedIndexableFiles: Boolean,
|
||||
fileStatuses: Sequence<Pair<FileId, Boolean>>): Pair<NonIndexableFilesInFilterGroup, IndexableFilesNotInFilterGroup> {
|
||||
fileStatuses: Sequence<Pair<FileId, Boolean>>): HealthCheckFinished {
|
||||
val nonIndexableFilesInFilter = mutableListOf<FileId>()
|
||||
val indexableFilesNotInFilter = mutableListOf<FileId>()
|
||||
|
||||
@@ -187,8 +194,8 @@ class ProjectIndexableFilesFilterHealthCheck(private val project: Project, priva
|
||||
}
|
||||
}
|
||||
|
||||
return NonIndexableFilesInFilterGroup(nonIndexableFilesInFilter) to
|
||||
IndexableFilesNotInFilterGroup(indexableFilesNotInFilter, shouldBeIndexable)
|
||||
return HealthCheckFinished(NonIndexableFilesInFilterGroup(nonIndexableFilesInFilter),
|
||||
IndexableFilesNotInFilterGroup(indexableFilesNotInFilter, shouldBeIndexable))
|
||||
}
|
||||
|
||||
private fun getFilesThatShouldBeIndexable(project: Project): IndexableFiles {
|
||||
@@ -314,3 +321,8 @@ private class IndexableFiles {
|
||||
return perProvider.find { it.second.get(fileId) }?.first
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface HealthCheckResult
|
||||
|
||||
private class HealthCheckFinished(val nonIndexableFilesInFilter: NonIndexableFilesInFilterGroup, val indexableFilesNotInFilter: IndexableFilesNotInFilterGroup) : HealthCheckResult
|
||||
private class HealthCheckCancelled(val reason: FilterActionCancellationReason) : HealthCheckResult
|
||||
|
||||
Reference in New Issue
Block a user