[perf-tests] AT-3378 Check if Project View has already been initialized before waiting for it

(cherry picked from commit 625c67011827adcb1fdc71640d477a2b7950e4ad)

IJ-CR-180256

GitOrigin-RevId: e5eba674585fbb16aaeef69be4097e2b060807dd
This commit is contained in:
Eugene Morozov
2025-11-04 13:26:39 +00:00
committed by intellij-monorepo-bot
parent 1fdce8e1b5
commit 9d5ee22397
2 changed files with 15 additions and 2 deletions
@@ -12,12 +12,14 @@ import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context
import org.jetbrains.annotations.ApiStatus.Internal
import org.jetbrains.annotations.TestOnly
import java.util.concurrent.atomic.AtomicBoolean
private val projectViewInit: Scope = Scope("projectViewInit")
@Service(Service.Level.PROJECT)
internal class ProjectViewInitNotifier(private val project: Project) {
@Internal
class ProjectViewInitNotifier(private val project: Project) {
private val startedOccurred = AtomicBoolean()
private val cachedNodesLoadedOccurred = AtomicBoolean()
private val completedOccurred = AtomicBoolean()
@@ -45,6 +47,9 @@ internal class ProjectViewInitNotifier(private val project: Project) {
project.messageBus.syncPublisher(ProjectViewListener.TOPIC).initCompleted()
}
@TestOnly
fun isInitCompleted(): Boolean = completedOccurred.get()
private inner class TracingHelper {
private val mainSpan = Ref<Span>()
private val cachedNodesSpan = Ref<Span>()
@@ -1,15 +1,17 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.jetbrains.performancePlugin.commands
import com.intellij.ide.projectView.impl.ProjectViewInitNotifier
import com.intellij.ide.projectView.impl.ProjectViewListener
import com.intellij.openapi.ui.playback.PlaybackContext
import com.intellij.openapi.ui.playback.commands.PlaybackCommandCoroutineAdapter
import kotlinx.coroutines.sync.Mutex
import org.jetbrains.annotations.TestOnly
/**
* Wait till a project tree is fully initialized.
* Command should be executed as soon as possible since project view initialization happens very early and the command might hang.
*/
@TestOnly
class WaitForProjectViewCommand(text: String, line: Int) : PlaybackCommandCoroutineAdapter(text, line) {
companion object {
@@ -17,6 +19,9 @@ class WaitForProjectViewCommand(text: String, line: Int) : PlaybackCommandCorout
}
override suspend fun doExecute(context: PlaybackContext) {
val notifier = context.project.getService(ProjectViewInitNotifier::class.java)
if (notifier.isInitCompleted()) return
val connection = context.project.messageBus.connect()
val mutex = Mutex(true)
connection.subscribe(ProjectViewListener.TOPIC, object : ProjectViewListener {
@@ -24,6 +29,9 @@ class WaitForProjectViewCommand(text: String, line: Int) : PlaybackCommandCorout
mutex.unlock()
}
})
if (notifier.isInitCompleted()) mutex.unlock()
mutex.lock()
connection.disconnect()
}