open editor as soon as workspace index is ready to use

GitOrigin-RevId: 29461d3dd47b1efa345876a12b1988c2f8d92e41
This commit is contained in:
Vladimir Krivosheev
2024-03-16 17:37:01 +00:00
committed by intellij-monorepo-bot
parent b38b51120d
commit 1c5a987807
7 changed files with 27 additions and 20 deletions
@@ -13,7 +13,7 @@ import com.intellij.openapi.project.impl.ProjectServiceContainerInitializedListe
import kotlinx.coroutines.launch
private class ProjectRunConfigurationInitializer : ProjectServiceContainerInitializedListener {
override suspend fun execute(project: Project) {
override suspend fun execute(project: Project, workspaceIndexReady: () -> Unit) {
val coroutineTracer = CoroutineTracerShim.coroutineTracer
@Suppress("UsagesOfObsoleteApi")
(project as ComponentManagerEx).getCoroutineScope().launch(coroutineTracer.rootTrace()) {
@@ -53,7 +53,7 @@ private fun setupOpenTelemetryReporting(meter: Meter) {
}
private class ModuleBridgeLoaderService : ProjectServiceContainerInitializedListener {
override suspend fun execute(project: Project) {
override suspend fun execute(project: Project, workspaceIndexReady: () -> Unit) {
coroutineScope {
val projectModelSynchronizer = project.serviceAsync<JpsProjectModelSynchronizer>()
val workspaceModel = project.serviceAsync<WorkspaceModel>() as WorkspaceModelImpl
@@ -118,6 +118,9 @@ private class ModuleBridgeLoaderService : ProjectServiceContainerInitializedList
WorkspaceModelCacheImpl.invalidateCaches()
throw RuntimeException(e)
}
finally {
workspaceIndexReady()
}
}
moduleLoadingTimeMs.addElapsedTime(start)
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.ide.lightEdit.project
import com.intellij.ide.impl.runUnderModalProgressIfIsEdt
@@ -39,7 +39,7 @@ internal class LightEditProjectImpl private constructor(projectPath: Path) :
this@LightEditProjectImpl.createComponentsNonBlocking()
}
projectInitListeners {
it.execute(this@LightEditProjectImpl)
it.execute(this@LightEditProjectImpl, workspaceIndexReady = {})
}
}
}
@@ -133,7 +133,6 @@ private class FrameAllocatorProjectInitObserver(
}
launch {
rawProjectDeferred.join()
span("project frame assigning") {
frameHelper.setProject(project)
}
@@ -174,13 +173,13 @@ internal class ProjectUiFrameAllocator(@JvmField val options: OpenProjectTask,
val projectInitObserver = FrameAllocatorProjectInitObserver(coroutineScope = loadingScope,
deferredProjectFrameHelper = deferredProjectFrameHelper)
val rawProjectDeferred = projectInitObserver.rawProjectDeferred
async(CoroutineName("project frame creating")) {
createFrameManager(loadingScope = loadingScope, deferredProjectFrameHelper = deferredProjectFrameHelper)
}
val startOfWaitingForReadyFrame = AtomicLong(-1)
val rawProjectDeferred = projectInitObserver.rawProjectDeferred
val reopeningEditorJob = outOfLoadingScope.launch {
val project = rawProjectDeferred.await()
span("restoreEditors") {
@@ -681,7 +681,7 @@ open class ProjectManagerImpl : ProjectManagerEx(), Disposable {
try {
try {
// cancel async preloading of services as soon as possible
(project as ComponentManagerEx).getCoroutineScope().coroutineContext.job.cancelAndJoin()
(project as ProjectImpl).getCoroutineScope().coroutineContext.job.cancelAndJoin()
}
catch (secondException: Throwable) {
e.addSuppressed(secondException)
@@ -1226,15 +1226,19 @@ private suspend fun initProject(file: Path,
val isTrusted = async { !isTrustCheckNeeded || checkOldTrustedStateAndMigrate(project, file) }
val beforeComponentCreation = projectInitObserver?.beforeInitRawProject(project)
val workspaceIndexReady = CompletableDeferred<Unit>()
launch {
workspaceIndexReady.join()
projectInitObserver?.rawProjectDeferred?.complete(project)
if (preloadServices) {
schedulePreloadServices(project)
}
}
projectInitListeners {
it.execute(project)
it.execute(project = project, workspaceIndexReady = { workspaceIndexReady.complete(Unit) })
}
projectInitObserver?.rawProjectDeferred?.complete(project)
if (preloadServices) {
schedulePreloadServices(project)
}
workspaceIndexReady.complete(Unit)
launch {
beforeComponentCreation?.join()
@@ -1263,8 +1267,7 @@ private suspend fun initProject(file: Path,
}
internal suspend inline fun projectInitListeners(crossinline executor: suspend (ProjectServiceContainerInitializedListener) -> Unit) {
val extensionArea = ApplicationManager.getApplication().extensionArea as ExtensionsAreaImpl
val ep = extensionArea
val ep = (ApplicationManager.getApplication().extensionArea as ExtensionsAreaImpl)
.getExtensionPoint<ProjectServiceContainerInitializedListener>("com.intellij.projectServiceContainerInitializedListener")
for (adapter in ep.sortedAdapters) {
val pluginDescriptor = adapter.pluginDescriptor
@@ -1272,7 +1275,7 @@ internal suspend inline fun projectInitListeners(crossinline executor: suspend (
!(pluginDescriptor.pluginId.idString == "com.jetbrains.codeWithMe"
&& adapter.assignableToClassName == "com.jetbrains.rdserver.unattendedHost.UnattendedHostManager\$ProjectAttachActivity")
&& !(pluginDescriptor.pluginId.idString == "intellij.rider.plugins.cwm"
&& adapter.assignableToClassName == "com.jetbrains.rdserver.unattendedHost.UnattendedHostManager\$ProjectAttachActivity")) {
&& adapter.assignableToClassName == "com.jetbrains.rdserver.unattendedHost.UnattendedHostManager\$ProjectAttachActivity")) {
LOG.error(PluginException("Plugin $pluginDescriptor is not approved to add ${ep.name}", pluginDescriptor.pluginId))
continue
}
@@ -1287,7 +1290,7 @@ private suspend fun confirmOpenNewProject(options: OpenProjectTask): Int {
return GeneralSettings.OPEN_PROJECT_NEW_WINDOW
}
var mode = GeneralSettings.getInstance().confirmOpenNewProject
var mode = serviceAsync<GeneralSettings>().confirmOpenNewProject
if (mode == GeneralSettings.OPEN_PROJECT_ASK) {
val ideUICustomization = serviceAsync<IdeUICustomization>()
val message = if (options.projectName == null) {
@@ -1345,7 +1348,7 @@ interface ProjectServiceContainerInitializedListener {
/**
* Invoked after container configured.
*/
suspend fun execute(project: Project)
suspend fun execute(project: Project, workspaceIndexReady: () -> Unit)
}
@TestOnly
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.wm.impl
import com.intellij.ide.RecentProjectsManager
@@ -12,6 +12,7 @@ import com.intellij.openapi.application.ApplicationNamesInfo
import com.intellij.openapi.application.EDT
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.impl.LaterInvocator
import com.intellij.openapi.components.serviceAsync
import com.intellij.openapi.components.serviceIfCreated
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.diagnostic.debug
@@ -308,7 +309,7 @@ open class ProjectFrameHelper internal constructor(
internal suspend fun setProject(project: Project) {
rootPane.setProject(project)
activationTimestamp?.let {
RecentProjectsManager.getInstance().setActivationTimestamp(project, it)
serviceAsync<RecentProjectsManager>().setActivationTimestamp(project, it)
}
}
@@ -10,6 +10,7 @@
overrides="true"/>
<projectServiceContainerInitializedListener
id="moduleBridgeLoaderService"
implementation="com.intellij.workspaceModel.ide.impl.legacyBridge.module.ModuleBridgeLoaderService" order="first"/>
<projectService serviceInterface="com.intellij.openapi.module.AutomaticModuleUnloader"
serviceImplementation="com.intellij.openapi.module.impl.AutomaticModuleUnloaderImpl" overrides="true"/>