From bae7d4cc52275746efba577c5d0d1feb8a952024 Mon Sep 17 00:00:00 2001 From: Sergei Vorobyov Date: Fri, 2 Aug 2024 20:27:20 +0200 Subject: [PATCH] IDEA-350883 [Gradle|Sync|FUS] new: added isFirstSyncWithIDEACaches flag for Gradle sync statistics events This flag identifies the presence of IDE external system caches before the first Gradle sync. * The true means that the Gradle sync is the first sync for the current project after opening and the project was opened WITH caches; * The false means that the Gradle sync is the first sync for the current project after opening and the project was opened WITHOUT caches; * The absence of this flag means the one out of two: - The Gradle sync is the secondary in the current project (the project wasn't closed); - The project was closed before the sync end. GitOrigin-RevId: 86109727eb944560d263861f7be265cc2c46b30e --- .../api-dump-unreviewed.txt | 1 + .../model/ExternalSystemDataKeys.java | 1 + .../manage/ExternalProjectsDataStorage.java | 3 +++ .../ExternalSystemSyncActionsCollector.kt | 22 +++++++++++++++---- .../util/ExternalSystemUtil.java | 1 + .../gradle/statistics/GradleSyncCollector.kt | 12 +++++++++- 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/platform/external-system-impl/api-dump-unreviewed.txt b/platform/external-system-impl/api-dump-unreviewed.txt index 1b095d20f75c..b45a17202342 100644 --- a/platform/external-system-impl/api-dump-unreviewed.txt +++ b/platform/external-system-impl/api-dump-unreviewed.txt @@ -141,6 +141,7 @@ f:com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys - sf:EXTERNAL_SYSTEM_ID:com.intellij.openapi.actionSystem.DataKey - sf:NEWLY_CREATED_PROJECT:com.intellij.openapi.util.Key - sf:NEWLY_IMPORTED_PROJECT:com.intellij.openapi.util.Key +- sf:NEWLY_OPENED_PROJECT_WITH_IDE_CACHES:com.intellij.openapi.util.Key - sf:NOTIFICATION_GROUP:com.intellij.openapi.actionSystem.DataKey - sf:PROJECTS_TREE:com.intellij.openapi.actionSystem.DataKey - sf:SELECTED_NODES:com.intellij.openapi.actionSystem.DataKey diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/ExternalSystemDataKeys.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/ExternalSystemDataKeys.java index 1bae1b337fdf..c42fbc2e1cd9 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/ExternalSystemDataKeys.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/model/ExternalSystemDataKeys.java @@ -25,6 +25,7 @@ public final class ExternalSystemDataKeys { @NotNull public static final Key NEWLY_IMPORTED_PROJECT = new Key<>("external.system.newly.imported"); @NotNull public static final Key NEWLY_CREATED_PROJECT = new Key<>("external.system.newly.created"); + @NotNull public static final Key NEWLY_OPENED_PROJECT_WITH_IDE_CACHES = new Key<>("external.system.newly.opened.with.ide.caches"); private ExternalSystemDataKeys() { } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsDataStorage.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsDataStorage.java index ff5a8d68a457..11ab00b51d69 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsDataStorage.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsDataStorage.java @@ -116,6 +116,9 @@ public final class ExternalProjectsDataStorage extends SimpleModificationTracker List projectInfos = load(myProject); readEnd = System.currentTimeMillis(); + boolean isOpenedProjectWithIdeCaches = projectInfos != null && !projectInfos.isEmpty(); + myProject.putUserData(ExternalSystemDataKeys.NEWLY_OPENED_PROJECT_WITH_IDE_CACHES, isOpenedProjectWithIdeCaches); + boolean isOpenedProject = hasLinkedExternalProjects() && !ExternalSystemUtil.isNewProject(myProject); if (projectInfos == null || (projectInfos.isEmpty() && isOpenedProject)) { markDirtyAllExternalProjects(); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/statistics/ExternalSystemSyncActionsCollector.kt b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/statistics/ExternalSystemSyncActionsCollector.kt index a8764b5ae2c5..79d8ba5a83ea 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/statistics/ExternalSystemSyncActionsCollector.kt +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/statistics/ExternalSystemSyncActionsCollector.kt @@ -13,6 +13,7 @@ import com.intellij.internal.statistic.eventLog.events.EventPair import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector import com.intellij.internal.statistic.utils.getPluginInfoById import com.intellij.internal.statistic.utils.platformPlugin +import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys import com.intellij.openapi.externalSystem.model.ExternalSystemException import com.intellij.openapi.project.Project import org.jetbrains.annotations.ApiStatus @@ -31,7 +32,7 @@ enum class Phase { GRADLE_CALL, PROJECT_RESOLVERS, DATA_SERVICES, WORKSPACE_MODE object ExternalSystemSyncActionsCollector : CounterUsagesCollector() { override fun getGroup(): EventLogGroup = GROUP - val GROUP = EventLogGroup("build.gradle.import", 9) + val GROUP = EventLogGroup("build.gradle.import", 10) private val activityIdField = EventFields.Long("ide_activity_id") private val importPhaseField = EventFields.Enum("phase") @@ -40,9 +41,10 @@ object ExternalSystemSyncActionsCollector : CounterUsagesCollector() { private val isParallelModelFetch = Boolean("parallel_model_fetch") private val isSyncSuccessful = Boolean("sync_successful") + private val isFirstSyncWithIdeCaches = Boolean("first_sync_with_ide_caches") val syncFinishedEvent = GROUP.registerVarargEvent("gradle.sync.finished", activityIdField, DurationMs, - isParallelModelFetch, isSyncSuccessful) + isParallelModelFetch, isSyncSuccessful, isFirstSyncWithIdeCaches) private val phaseStartedEvent = GROUP.registerEvent("phase.started", activityIdField, importPhaseField) @@ -68,7 +70,12 @@ object ExternalSystemSyncActionsCollector : CounterUsagesCollector() { private val ourErrorsRateThrottle = EventsRateThrottle(100, 5L * 60 * 1000) // 100 errors per 5 minutes - data class GradleSyncDetails(val timestamp: Long, val parallelModelFetchEnabled: Boolean) + private class GradleSyncDetails( + val timestamp: Long, + val parallelModelFetchEnabled: Boolean, + val isFirstSyncWithIdeCaches: Boolean?, + ) + private const val tsCacheCapasity = 100 private val idToStartTS = object: LinkedHashMap(tsCacheCapasity) { override fun removeEldestEntry(eldest: MutableMap.MutableEntry?): Boolean { @@ -78,7 +85,11 @@ object ExternalSystemSyncActionsCollector : CounterUsagesCollector() { @JvmStatic fun logSyncStarted(project: Project?, activityId: Long, parallelModelFetchEnabled: Boolean) { - idToStartTS[activityId] = GradleSyncDetails(System.currentTimeMillis(), parallelModelFetchEnabled) + idToStartTS[activityId] = GradleSyncDetails( + System.currentTimeMillis(), + parallelModelFetchEnabled, + project?.getUserData(ExternalSystemDataKeys.NEWLY_OPENED_PROJECT_WITH_IDE_CACHES) + ) syncStartedEvent.log(project, activityId) } @@ -91,6 +102,9 @@ object ExternalSystemSyncActionsCollector : CounterUsagesCollector() { if (syncDetails != null) { add(DurationMs with nowTS - syncDetails.timestamp) add(isParallelModelFetch with syncDetails.parallelModelFetchEnabled) + if (syncDetails.isFirstSyncWithIdeCaches != null) { + add(isFirstSyncWithIdeCaches with syncDetails.isFirstSyncWithIdeCaches) + } } else { add(DurationMs with -1) diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java index e54d497e02f1..3c27f52a017d 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/util/ExternalSystemUtil.java @@ -634,6 +634,7 @@ public final class ExternalSystemUtil { } project.putUserData(ExternalSystemDataKeys.NEWLY_CREATED_PROJECT, null); project.putUserData(ExternalSystemDataKeys.NEWLY_IMPORTED_PROJECT, null); + project.putUserData(ExternalSystemDataKeys.NEWLY_OPENED_PROJECT_WITH_IDE_CACHES, null); eventDispatcher.onEvent(taskId, getSyncFinishEvent(taskId, finishSyncEventSupplier)); } } diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/statistics/GradleSyncCollector.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/statistics/GradleSyncCollector.kt index 5fdab4d6348d..a52522a2e46c 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/statistics/GradleSyncCollector.kt +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/statistics/GradleSyncCollector.kt @@ -7,6 +7,7 @@ import com.intellij.internal.statistic.eventLog.EventLogGroup import com.intellij.internal.statistic.eventLog.events.EventFields import com.intellij.internal.statistic.eventLog.events.LongEventField import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector +import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys import org.jetbrains.annotations.ApiStatus import org.jetbrains.plugins.gradle.service.project.DefaultProjectResolverContext import java.util.* @@ -17,11 +18,12 @@ internal object GradleSyncCollector : CounterUsagesCollector() { override fun getGroup(): EventLogGroup = GROUP - private val GROUP = EventLogGroup("gradle.sync", 1) + private val GROUP = EventLogGroup("gradle.sync", 2) private val ACTIVITY_ID = EventFields.Long("ide_activity_id") private val MODEL_FETCH_FOR_BUILD_SRC = EventFields.Boolean("model_fetch_for_build_src") + private val MODEL_FETCH_WITH_IDE_CACHES = EventFields.Boolean("first_model_fetch_with_ide_caches") private val MODEL_FETCH_ERROR_COUNT = EventFields.Int("model_fetch_error_count") private val MODEL_FETCH_COMPLETION_STAMP = EventFields.Long("model_fetch_completion_stamp") @@ -37,6 +39,7 @@ internal object GradleSyncCollector : CounterUsagesCollector() { ACTIVITY_ID, MODEL_FETCH_FOR_BUILD_SRC, + MODEL_FETCH_WITH_IDE_CACHES, MODEL_FETCH_ERROR_COUNT, MODEL_FETCH_COMPLETION_STAMP, @@ -58,6 +61,10 @@ internal object GradleSyncCollector : CounterUsagesCollector() { private val exceptions = ArrayList() + private val isFirstModelFetchWithIdeCaches: Boolean? = + context.externalSystemTaskId.findProject() + ?.getUserData(ExternalSystemDataKeys.NEWLY_OPENED_PROJECT_WITH_IDE_CACHES) + fun logModelFetchPhaseCompleted(phase: GradleModelFetchPhase) { val currentStamp = GlobalStamp.now() val phaseCompletionStamp = currentStamp - modelFetchStartStamp @@ -73,6 +80,9 @@ internal object GradleSyncCollector : CounterUsagesCollector() { val project = context.externalSystemTaskId.findProject() MODEL_FETCH_COMPLETED_EVENT.log(project) { add(ACTIVITY_ID with context.externalSystemTaskId.id) + if (isFirstModelFetchWithIdeCaches != null) { + add(MODEL_FETCH_WITH_IDE_CACHES with isFirstModelFetchWithIdeCaches) + } add(MODEL_FETCH_FOR_BUILD_SRC with context.isBuildSrcProject) add(MODEL_FETCH_ERROR_COUNT with exceptions.size) val modelFetchStamp = currentStamp - modelFetchStartStamp