IDEA-246164 Loading components takes lots of time, sometimes hangs forever

GitOrigin-RevId: 63ba3f31f512878d96ffa2fe9fce510fb53a0099
This commit is contained in:
Vladimir Krivosheev
2020-07-20 07:18:31 +00:00
committed by intellij-monorepo-bot
parent 9a01d5e505
commit 89f6f95f38
8 changed files with 46 additions and 35 deletions
@@ -1,7 +1,6 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.configurationStore
import com.intellij.openapi.application.AccessToken
import com.intellij.openapi.components.ComponentManager
/**
@@ -22,8 +21,5 @@ internal class HeadlessSaveAndSyncHandler : BaseSaveAndSyncHandler() {
override fun unblockSyncOnFrameActivation() {}
override fun saveSettingsUnderModalProgress(componentManager: ComponentManager): Boolean {
StoreUtil.saveSettings(componentManager, forceSavingAllSettings = true)
return true
}
override fun saveSettingsUnderModalProgress(componentManager: ComponentManager) = true
}
@@ -22,7 +22,6 @@ import com.intellij.util.io.exists
import com.intellij.util.io.systemIndependentPath
import com.intellij.util.messages.MessageBus
import com.intellij.util.text.nullize
import kotlinx.coroutines.runBlocking
import java.nio.file.Path
import java.util.*
import kotlin.collections.ArrayList
@@ -60,9 +59,7 @@ abstract class ProjectStoreBase(final override val project: Project) : Component
final override fun clearStorages() = storageManager.clearStorages()
private fun loadProjectFromTemplate(defaultProject: Project) {
val stateStore = defaultProject.stateStore as DefaultProjectStoreImpl
runBlocking { stateStore.save() }
val element = stateStore.getStateCopy() ?: return
val element = (defaultProject.stateStore as DefaultProjectStoreImpl).getStateCopy() ?: return
LOG.runAndLogException {
val dotIdea = dotIdea
if (dotIdea != null) {
@@ -1,6 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.configurationStore
import com.intellij.CommonBundle
import com.intellij.conversion.ConversionService
import com.intellij.ide.FrameStateListener
import com.intellij.ide.GeneralSettings
@@ -173,10 +174,6 @@ internal class SaveAndSyncHandlerImpl : BaseSaveAndSyncHandler(), Disposable {
}
}
override fun cancelScheduledSave() {
saveAlarm.cancel()
}
private fun waitForScheduledSave() {
if (saveAlarm.isEmpty) {
return
@@ -212,7 +209,8 @@ internal class SaveAndSyncHandlerImpl : BaseSaveAndSyncHandler(), Disposable {
runInAutoSaveDisabledMode {
edtPoolDispatcherManager.processTasks()
ProgressManager.getInstance().run(object : Task.Modal(componentManager as? Project, "Saving " + (if (componentManager is Application) "Application" else "Project"), /* canBeCancelled = */ false) {
val project = (componentManager as? Project)?.takeIf { !it.isDefault }
ProgressManager.getInstance().run(object : Task.Modal(project, getProgressTitle(componentManager), /* canBeCancelled = */ false) {
override fun run(indicator: ProgressIndicator) {
indicator.isIndeterminate = true
@@ -301,6 +299,7 @@ internal class SaveAndSyncHandlerImpl : BaseSaveAndSyncHandler(), Disposable {
override fun blockSaveOnFrameDeactivation() {
LOG.debug("save blocked")
saveAlarm.cancel()
blockSaveOnFrameDeactivationCount.incrementAndGet()
}
@@ -324,4 +323,12 @@ private val saveAppAndProjectsSettingsTask = SaveAndSyncHandler.SaveTask(saveDoc
internal abstract class BaseSaveAndSyncHandler : SaveAndSyncHandler() {
internal val edtPoolDispatcherManager = EdtPoolDispatcherManager()
}
private fun getProgressTitle(componentManager: ComponentManager): String {
return when {
componentManager is Application -> CommonBundle.message("title.save.app")
(componentManager as Project).isDefault -> CommonBundle.message("title.save.default.project")
else -> CommonBundle.message("title.save.project")
}
}
@@ -100,3 +100,7 @@ title.input=Input
title.name=Name
title.confirmation=Confirmation
title.console=Console
title.save.app=Saving Application
title.save.project=Saving Project
title.save.default.project=Saving Default Project
@@ -72,11 +72,7 @@ abstract class SaveAndSyncHandler {
open fun maybeRefresh(modalityState: ModalityState) {
}
@ApiStatus.Experimental
open fun cancelScheduledSave() {
}
@ApiStatus.Experimental
@ApiStatus.Internal
abstract fun saveSettingsUnderModalProgress(componentManager: ComponentManager): Boolean
/**
@@ -9,7 +9,6 @@ import com.intellij.ide.plugins.PluginUtil
import com.intellij.notification.Notification
import com.intellij.notification.NotificationGroup
import com.intellij.notification.NotificationType
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ApplicationNamesInfo
import com.intellij.openapi.application.TransactionGuardImpl
@@ -21,7 +20,7 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.processOpenedProjects
import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.ExceptionUtil
import kotlinx.coroutines.runBlocking
import org.jetbrains.annotations.CalledInAny
import org.jetbrains.annotations.CalledInAwt
@@ -41,11 +40,10 @@ class StoreUtil private constructor() {
@JvmStatic
@CalledInAny
fun saveSettings(componentManager: ComponentManager, forceSavingAllSettings: Boolean = false) {
if (componentManager is Application) {
SaveAndSyncHandler.getInstance().cancelScheduledSave()
}
runBlocking {
com.intellij.configurationStore.saveSettings(componentManager, forceSavingAllSettings)
runInAutoSaveDisabledMode {
runBlocking {
com.intellij.configurationStore.saveSettings(componentManager, forceSavingAllSettings)
}
}
}
@@ -69,11 +67,11 @@ class StoreUtil private constructor() {
@CalledInAwt
@JvmStatic
fun saveDocumentsAndProjectsAndApp(forceSavingAllSettings: Boolean) {
SaveAndSyncHandler.getInstance().cancelScheduledSave()
FileDocumentManager.getInstance().saveAllDocuments()
runBlocking {
saveProjectsAndApp(forceSavingAllSettings)
runInAutoSaveDisabledMode {
FileDocumentManager.getInstance().saveAllDocuments()
runBlocking {
saveProjectsAndApp(forceSavingAllSettings)
}
}
}
}
@@ -101,7 +99,7 @@ suspend fun saveSettings(componentManager: ComponentManager, forceSavingAllSetti
}
val messagePostfix = IdeBundle.message("notification.content.please.restart.0", ApplicationNamesInfo.getInstance().fullProductName,
(if (ApplicationManager.getApplication().isInternal) "<p>" + StringUtil.getThrowableText(e) + "</p>" else ""))
(if (ApplicationManager.getApplication().isInternal) "<p>" + ExceptionUtil.getThrowableText(e) + "</p>" else ""))
val pluginId = PluginUtil.getInstance().findPluginId(e)
val groupId = NotificationGroup.createIdWithTitle("Settings Error", IdeBundle.message("notification.group.settings.error"))
@@ -1,12 +1,14 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.project.impl
import com.intellij.configurationStore.saveSettings
import com.intellij.conversion.CannotConvertException
import com.intellij.diagnostic.PluginException
import com.intellij.diagnostic.runActivity
import com.intellij.diagnostic.runMainActivity
import com.intellij.ide.RecentProjectsManager
import com.intellij.ide.RecentProjectsManagerBase
import com.intellij.ide.SaveAndSyncHandler
import com.intellij.ide.impl.OpenProjectTask
import com.intellij.ide.plugins.StartupAbortedException
import com.intellij.idea.SplashManager
@@ -17,6 +19,7 @@ import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.Task
import com.intellij.openapi.progress.impl.CoreProgressManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.wm.WindowManager
@@ -27,6 +30,7 @@ import com.intellij.ui.ComponentUtil
import com.intellij.ui.IdeUICustomization
import com.intellij.ui.ScreenUtil
import com.intellij.ui.scale.ScaleContext
import kotlinx.coroutines.runBlocking
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.CalledInAwt
import java.awt.Dimension
@@ -36,8 +40,13 @@ import java.io.EOFException
import java.nio.file.Path
import kotlin.math.min
internal open class ProjectFrameAllocator {
internal open class ProjectFrameAllocator(private val options: OpenProjectTask) {
open fun <T : Any> run(task: () -> T?): T? {
if (options.isNewProject && options.useDefaultProjectAsTemplate && options.project == null) {
runBlocking {
saveSettings(ProjectManager.getInstance().defaultProject, forceSavingAllSettings = true)
}
}
return task()
}
@@ -53,7 +62,7 @@ internal open class ProjectFrameAllocator {
open fun projectOpened(project: Project) {}
}
internal class ProjectUiFrameAllocator(private var options: OpenProjectTask, private val projectStoreBaseDir: Path) : ProjectFrameAllocator() {
internal class ProjectUiFrameAllocator(private var options: OpenProjectTask, private val projectStoreBaseDir: Path) : ProjectFrameAllocator(options) {
// volatile not required because created in run (before executing run task)
private var frameHelper: ProjectFrameHelper? = null
@@ -66,6 +75,10 @@ internal class ProjectUiFrameAllocator(private var options: OpenProjectTask, pri
var result: T? = null
val progressTitle = getProgressTitle()
ApplicationManager.getApplication().invokeAndWait {
if (options.isNewProject && options.useDefaultProjectAsTemplate && options.project == null) {
SaveAndSyncHandler.getInstance().saveSettingsUnderModalProgress(ProjectManager.getInstance().defaultProject)
}
val frame = createFrameIfNeeded()
val progressTask = object : Task.Modal(null, progressTitle, true) {
override fun run(indicator: ProgressIndicator) {
@@ -92,7 +92,7 @@ open class ProjectManagerExImpl : ProjectManagerImpl() {
}
}
val frameAllocator = if (app.isHeadlessEnvironment) ProjectFrameAllocator() else ProjectUiFrameAllocator(options, projectStoreBaseDir)
val frameAllocator = if (app.isHeadlessEnvironment) ProjectFrameAllocator(options) else ProjectUiFrameAllocator(options, projectStoreBaseDir)
val result = runInAutoSaveDisabledMode {
frameAllocator.run {
activity.end()