mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-14 18:05:27 +07:00
IJPL-166 enable coroutine dump a little bit later, log error
GitOrigin-RevId: 214a83e6855634ecc47c6cf8b17f4920336f729a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
082d393a4b
commit
b6bbebcdae
@@ -4,7 +4,10 @@
|
||||
@file:Suppress("RAW_RUN_BLOCKING")
|
||||
package com.intellij.platform.ide.bootstrap
|
||||
|
||||
import com.intellij.diagnostic.COROUTINE_DUMP_HEADER
|
||||
import com.intellij.diagnostic.LoadingState
|
||||
import com.intellij.diagnostic.dumpCoroutines
|
||||
import com.intellij.diagnostic.enableCoroutineDump
|
||||
import com.intellij.ide.*
|
||||
import com.intellij.ide.bootstrap.InitAppContext
|
||||
import com.intellij.ide.gdpr.EndUserAgreement
|
||||
@@ -47,6 +50,7 @@ import com.intellij.util.PlatformUtils
|
||||
import com.intellij.util.io.URLUtil
|
||||
import com.intellij.util.io.createDirectories
|
||||
import com.intellij.util.lang.ZipFilePool
|
||||
import com.jetbrains.JBR
|
||||
import kotlinx.coroutines.*
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import org.jetbrains.annotations.VisibleForTesting
|
||||
@@ -178,13 +182,23 @@ internal suspend fun loadApp(app: ApplicationImpl,
|
||||
}
|
||||
}
|
||||
|
||||
val coroutineDebugJob = launch(CoroutineName("coroutine debug probes init")) {
|
||||
enableCoroutineDump().onFailure { e ->
|
||||
LOG.error("Cannot enable coroutine debug dump", e)
|
||||
}
|
||||
enableJstack()
|
||||
}
|
||||
|
||||
asyncScope.launch {
|
||||
launch(CoroutineName("checkThirdPartyPluginsAllowed")) {
|
||||
// do not use launch here - don't overload CPU, let some room for JIT and other CPU-intensive tasks during start-up
|
||||
coroutineDebugJob.join()
|
||||
|
||||
span("checkThirdPartyPluginsAllowed") {
|
||||
checkThirdPartyPluginsAllowed()
|
||||
}
|
||||
|
||||
// doesn't block app start-up
|
||||
launch(CoroutineName("post app init tasks")) {
|
||||
span("post app init tasks") {
|
||||
runPostAppInitTasks()
|
||||
}
|
||||
|
||||
@@ -197,6 +211,17 @@ internal suspend fun loadApp(app: ApplicationImpl,
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun enableJstack() {
|
||||
span("coroutine jstack configuration") {
|
||||
JBR.getJstack()?.includeInfoFrom {
|
||||
"""
|
||||
$COROUTINE_DUMP_HEADER
|
||||
${dumpCoroutines(stripDump = false)}
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun preInitApp(app: ApplicationImpl,
|
||||
asyncScope: CoroutineScope,
|
||||
initLafJob: Job,
|
||||
|
||||
@@ -26,9 +26,9 @@ private val LOG: Logger
|
||||
get() = logger<IdeStartupWizard>()
|
||||
|
||||
val isIdeStartupWizardEnabled: Boolean
|
||||
get() = !ApplicationManagerEx.isInIntegrationTest()
|
||||
&& System.getProperty ("intellij.startup.wizard", "true").toBoolean()
|
||||
&& IdeStartupExperiment.isExperimentEnabled()
|
||||
get() = !ApplicationManagerEx.isInIntegrationTest() &&
|
||||
System.getProperty ("intellij.startup.wizard", "true").toBoolean() &&
|
||||
IdeStartupExperiment.isExperimentEnabled()
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
internal suspend fun runStartupWizard(isInitialStart: Job, app: Application) {
|
||||
@@ -174,9 +174,9 @@ private object IdeStartupExperiment {
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun getGroupKind(group: Int) = when {
|
||||
PlatformUtils.isIdeaUltimate() || PlatformUtils.isPyCharmPro() -> when {
|
||||
group in 0..7 -> GroupKind.Experimental
|
||||
group == 8 || group == 9 -> GroupKind.Control
|
||||
PlatformUtils.isIdeaUltimate() || PlatformUtils.isPyCharmPro() -> when (group) {
|
||||
in 0..7 -> GroupKind.Experimental
|
||||
8, 9 -> GroupKind.Control
|
||||
else -> GroupKind.Undefined
|
||||
}
|
||||
else -> when (group) {
|
||||
@@ -186,12 +186,13 @@ private object IdeStartupExperiment {
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.asBucket() = MathUtil.nonNegativeAbs(this.hashCode()) % 256
|
||||
private fun asBucket(s: String) = MathUtil.nonNegativeAbs(s.hashCode()) % 256
|
||||
|
||||
private fun getBucket(): Int {
|
||||
val deviceId = LOG.runAndLogException {
|
||||
DeviceIdManager.getOrGenerateId(object : DeviceIdManager.DeviceIdToken {}, "FUS")
|
||||
} ?: return 0
|
||||
return deviceId.asBucket()
|
||||
return asBucket(deviceId)
|
||||
}
|
||||
|
||||
val experimentGroup by lazy {
|
||||
@@ -204,7 +205,7 @@ private object IdeStartupExperiment {
|
||||
experimentGroup
|
||||
}
|
||||
|
||||
val experimentGroupKind by lazy {
|
||||
val experimentGroupKind: GroupKind by lazy {
|
||||
getGroupKind(experimentGroup)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
// 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.platform.ide.bootstrap
|
||||
|
||||
import com.intellij.accessibility.enableScreenReaderSupportIfNecessary
|
||||
import com.intellij.ide.gdpr.EndUserAgreement
|
||||
import com.intellij.idea.AppMode
|
||||
import com.intellij.openapi.application.ConfigImportHelper
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.application.impl.RawSwingDispatcher
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.getOrLogException
|
||||
import com.intellij.openapi.util.IconLoader
|
||||
import com.intellij.openapi.util.registry.EarlyAccessRegistryManager
|
||||
import com.intellij.platform.diagnostic.telemetry.impl.span
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.CancellationException
|
||||
|
||||
internal suspend fun importConfigIfNeeded(isHeadless: Boolean,
|
||||
configImportNeededDeferred: Deferred<Boolean>,
|
||||
lockSystemDirsJob: Job,
|
||||
logDeferred: Deferred<Logger>,
|
||||
args: List<String>,
|
||||
targetDirectoryToImportConfig: Path?,
|
||||
appStarterDeferred: Deferred<AppStarter>,
|
||||
euaDocumentDeferred: Deferred<EndUserAgreement.Document?>,
|
||||
initLafJob: Job): Job? {
|
||||
if (isHeadless) {
|
||||
importConfigHeadless(configImportNeededDeferred = configImportNeededDeferred,
|
||||
lockSystemDirsJob = lockSystemDirsJob,
|
||||
logDeferred = logDeferred,
|
||||
args = args,
|
||||
targetDirectoryToImportConfig = targetDirectoryToImportConfig,
|
||||
appStarterDeferred = appStarterDeferred,
|
||||
euaDocumentDeferred = euaDocumentDeferred)
|
||||
return null
|
||||
}
|
||||
|
||||
if (AppMode.isRemoteDevHost() || !configImportNeededDeferred.await()) {
|
||||
return null
|
||||
}
|
||||
|
||||
initLafJob.join()
|
||||
val log = logDeferred.await()
|
||||
importConfig(
|
||||
args = args,
|
||||
targetDirectoryToImportConfig = targetDirectoryToImportConfig ?: PathManager.getConfigDir(),
|
||||
log = log,
|
||||
appStarter = appStarterDeferred.await(),
|
||||
euaDocumentDeferred = euaDocumentDeferred,
|
||||
)
|
||||
|
||||
if (ConfigImportHelper.isNewUser()) {
|
||||
enableNewUi(logDeferred)
|
||||
|
||||
if (isIdeStartupWizardEnabled) {
|
||||
log.info("Will enter initial app wizard flow.")
|
||||
val result = CompletableDeferred<Boolean>()
|
||||
isInitialStart = result
|
||||
return result
|
||||
}
|
||||
else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun importConfig(args: List<String>,
|
||||
targetDirectoryToImportConfig: Path,
|
||||
log: Logger,
|
||||
appStarter: AppStarter,
|
||||
euaDocumentDeferred: Deferred<EndUserAgreement.Document?>,
|
||||
headlessAutoImport: Boolean = false) {
|
||||
if (headlessAutoImport) {
|
||||
// headless AppStarters are not notified about config import
|
||||
val veryFirstStartOnThisComputer = euaDocumentDeferred.await() != null
|
||||
withContext(RawSwingDispatcher) {
|
||||
try {
|
||||
ConfigImportHelper.importConfigsTo(veryFirstStartOnThisComputer, targetDirectoryToImportConfig, args, log, true)
|
||||
log.info("Automatic config import completed")
|
||||
}
|
||||
catch (e: UnsupportedOperationException) {
|
||||
log.info("Automatic config import is not possible", e)
|
||||
}
|
||||
}
|
||||
EarlyAccessRegistryManager.invalidate()
|
||||
IconLoader.clearCache()
|
||||
return
|
||||
}
|
||||
|
||||
span("screen reader checking") {
|
||||
runCatching {
|
||||
enableScreenReaderSupportIfNecessary()
|
||||
}.getOrLogException(log)
|
||||
}
|
||||
|
||||
span("config importing") {
|
||||
appStarter.beforeImportConfigs()
|
||||
|
||||
val veryFirstStartOnThisComputer = euaDocumentDeferred.await() != null
|
||||
withContext(RawSwingDispatcher) {
|
||||
ConfigImportHelper.importConfigsTo(veryFirstStartOnThisComputer, targetDirectoryToImportConfig, args, log)
|
||||
}
|
||||
appStarter.importFinished(targetDirectoryToImportConfig)
|
||||
EarlyAccessRegistryManager.invalidate()
|
||||
IconLoader.clearCache()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun enableNewUi(logDeferred: Deferred<Logger>) {
|
||||
if (System.getProperty("ide.experimental.ui") == null) {
|
||||
try {
|
||||
EarlyAccessRegistryManager.setAndFlush(mapOf("ide.experimental.ui" to "true"))
|
||||
}
|
||||
catch (e: CancellationException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
logDeferred.await().error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun importConfigHeadless(configImportNeededDeferred: Deferred<Boolean>,
|
||||
lockSystemDirsJob: Job,
|
||||
logDeferred: Deferred<Logger>,
|
||||
args: List<String>,
|
||||
targetDirectoryToImportConfig: Path?,
|
||||
appStarterDeferred: Deferred<AppStarter>,
|
||||
euaDocumentDeferred: Deferred<EndUserAgreement.Document?>) {
|
||||
if (!configImportNeededDeferred.await()) {
|
||||
return
|
||||
}
|
||||
|
||||
// make sure we lock the dir before writing
|
||||
lockSystemDirsJob.join()
|
||||
if (!ConfigImportHelper.isHeadlessAutomaticConfigImportAllowed()) {
|
||||
enableNewUi(logDeferred)
|
||||
}
|
||||
else {
|
||||
val log = logDeferred.await()
|
||||
importConfig(
|
||||
args = args,
|
||||
targetDirectoryToImportConfig = targetDirectoryToImportConfig ?: PathManager.getConfigDir(),
|
||||
log = log,
|
||||
appStarter = appStarterDeferred.await(),
|
||||
euaDocumentDeferred = euaDocumentDeferred,
|
||||
headlessAutoImport = true
|
||||
)
|
||||
if (ConfigImportHelper.isNewUser()) {
|
||||
enableNewUi(logDeferred)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,9 @@
|
||||
package com.intellij.platform.ide.bootstrap
|
||||
|
||||
import com.intellij.BundleBase
|
||||
import com.intellij.accessibility.enableScreenReaderSupportIfNecessary
|
||||
import com.intellij.diagnostic.*
|
||||
import com.intellij.ide.*
|
||||
import com.intellij.ide.bootstrap.*
|
||||
import com.intellij.ide.gdpr.EndUserAgreement
|
||||
import com.intellij.ide.instrument.WriteIntentLockInstrumenter
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.idea.*
|
||||
@@ -22,10 +20,8 @@ import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.getOrLogException
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.IconLoader
|
||||
import com.intellij.openapi.util.ShutDownTracker
|
||||
import com.intellij.openapi.util.SystemInfoRt
|
||||
import com.intellij.openapi.util.registry.EarlyAccessRegistryManager
|
||||
import com.intellij.platform.diagnostic.telemetry.impl.OpenTelemetryConfigurator
|
||||
import com.intellij.platform.diagnostic.telemetry.impl.TelemetryManagerImpl
|
||||
import com.intellij.platform.diagnostic.telemetry.impl.span
|
||||
@@ -41,7 +37,6 @@ import com.intellij.util.lang.ZipFilePool
|
||||
import com.jetbrains.JBR
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdkBuilder
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import java.awt.Toolkit
|
||||
import java.lang.invoke.MethodHandles
|
||||
@@ -58,7 +53,6 @@ import java.util.function.BiConsumer
|
||||
import java.util.function.BiFunction
|
||||
import java.util.logging.ConsoleHandler
|
||||
import java.util.logging.Level
|
||||
import kotlin.concurrent.Volatile
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
internal const val IDE_STARTED: String = "------------------------------------------------------ IDE STARTED ------------------------------------------------------"
|
||||
@@ -89,6 +83,10 @@ private val commandProcessor: AtomicReference<(List<String>) -> Deferred<CliResu
|
||||
internal var shellEnvDeferred: Deferred<Boolean?>? = null
|
||||
private set
|
||||
|
||||
@Volatile
|
||||
@JvmField
|
||||
internal var isInitialStart: CompletableDeferred<Boolean>? = null
|
||||
|
||||
// the main thread's dispatcher is sequential - use it with care
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
fun CoroutineScope.startApplication(args: List<String>,
|
||||
@@ -133,6 +131,7 @@ fun CoroutineScope.startApplication(args: List<String>,
|
||||
val initBaseLafJob = launch {
|
||||
initUi(initAwtToolkitJob = initAwtToolkitJob, isHeadless = isHeadless, asyncScope = this@startApplication)
|
||||
}
|
||||
|
||||
if (!isHeadless) {
|
||||
val initUiScale = launch {
|
||||
if (SystemInfoRt.isMac) {
|
||||
@@ -147,7 +146,9 @@ fun CoroutineScope.startApplication(args: List<String>,
|
||||
}
|
||||
}
|
||||
|
||||
scheduleShowSplashIfNeeded(lockSystemDirsJob = lockSystemDirsJob, initUiScale = initUiScale, appInfoDeferred = appInfoDeferred,
|
||||
scheduleShowSplashIfNeeded(lockSystemDirsJob = lockSystemDirsJob,
|
||||
initUiScale = initUiScale,
|
||||
appInfoDeferred = appInfoDeferred,
|
||||
args = args)
|
||||
scheduleUpdateFrameClassAndWindowIconAndPreloadSystemFonts(initAwtToolkitJob = initAwtToolkitJob,
|
||||
initUiScale = initUiScale,
|
||||
@@ -201,67 +202,24 @@ fun CoroutineScope.startApplication(args: List<String>,
|
||||
}
|
||||
}
|
||||
|
||||
scheduleLoadSystemLibsAndLogInfoAndInitMacApp(logDeferred, appInfoDeferred, initLafJob, args, mainScope)
|
||||
scheduleLoadSystemLibsAndLogInfoAndInitMacApp(logDeferred = logDeferred,
|
||||
appInfoDeferred = appInfoDeferred,
|
||||
initUiDeferred = initLafJob,
|
||||
args = args,
|
||||
mainScope = mainScope)
|
||||
|
||||
val euaDocumentDeferred = async { loadEuaDocument(appInfoDeferred) }
|
||||
|
||||
val configImportDeferred: Deferred<Job?> = async {
|
||||
if (isHeadless) {
|
||||
if (!configImportNeededDeferred.await()) {
|
||||
return@async null
|
||||
}
|
||||
// make sure we lock the dir before writing
|
||||
lockSystemDirsJob.join()
|
||||
if (!ConfigImportHelper.isHeadlessAutomaticConfigImportAllowed()) {
|
||||
enableNewUi(logDeferred)
|
||||
}
|
||||
else {
|
||||
val log = logDeferred.await()
|
||||
importConfig(
|
||||
importConfigIfNeeded(isHeadless = isHeadless,
|
||||
configImportNeededDeferred = configImportNeededDeferred,
|
||||
lockSystemDirsJob = lockSystemDirsJob,
|
||||
logDeferred = logDeferred,
|
||||
args = args,
|
||||
targetDirectoryToImportConfig = targetDirectoryToImportConfig ?: PathManager.getConfigDir(),
|
||||
log = log,
|
||||
appStarter = appStarterDeferred.await(),
|
||||
targetDirectoryToImportConfig = targetDirectoryToImportConfig,
|
||||
appStarterDeferred = appStarterDeferred,
|
||||
euaDocumentDeferred = euaDocumentDeferred,
|
||||
headlessAutoImport = true
|
||||
)
|
||||
if (ConfigImportHelper.isNewUser()) {
|
||||
enableNewUi(logDeferred)
|
||||
}
|
||||
}
|
||||
return@async null
|
||||
}
|
||||
|
||||
if (AppMode.isRemoteDevHost() || !configImportNeededDeferred.await()) {
|
||||
return@async null
|
||||
}
|
||||
|
||||
initLafJob.join()
|
||||
val log = logDeferred.await()
|
||||
importConfig(
|
||||
args = args,
|
||||
targetDirectoryToImportConfig = targetDirectoryToImportConfig ?: PathManager.getConfigDir(),
|
||||
log = log,
|
||||
appStarter = appStarterDeferred.await(),
|
||||
euaDocumentDeferred = euaDocumentDeferred,
|
||||
)
|
||||
|
||||
if (ConfigImportHelper.isNewUser()) {
|
||||
enableNewUi(logDeferred)
|
||||
|
||||
if (isIdeStartupWizardEnabled) {
|
||||
log.info("Will enter initial app wizard flow.")
|
||||
val result = CompletableDeferred<Boolean>()
|
||||
isInitialStart = result
|
||||
result
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
initLafJob =initLafJob)
|
||||
}
|
||||
|
||||
val pluginSetDeferred = async {
|
||||
@@ -295,7 +253,7 @@ fun CoroutineScope.startApplication(args: List<String>,
|
||||
Class.forName(OpenTelemetrySdkBuilder::class.java.name, true, classLoader)
|
||||
}
|
||||
|
||||
val appLoaded = launch {
|
||||
val appLoaded = async {
|
||||
val initEventQueueJob = scheduleInitIdeEventQueue(initAwtToolkit = initAwtToolkitJob, isHeadless = isHeadless)
|
||||
|
||||
checkSystemDirJob.join()
|
||||
@@ -312,7 +270,7 @@ fun CoroutineScope.startApplication(args: List<String>,
|
||||
ApplicationImpl(CoroutineScope(mainScope.coroutineContext.job).namedChildScope("Application"), isInternal)
|
||||
}
|
||||
|
||||
val starter = loadApp(app = app,
|
||||
loadApp(app = app,
|
||||
initAwtToolkitAndEventQueueJob = initEventQueueJob,
|
||||
pluginSetDeferred = pluginSetDeferred,
|
||||
appInfoDeferred = appInfoDeferred,
|
||||
@@ -322,25 +280,7 @@ fun CoroutineScope.startApplication(args: List<String>,
|
||||
logDeferred = logDeferred,
|
||||
appRegisteredJob = appRegisteredJob,
|
||||
args = args.filterNot { CommandLineArgs.isKnownArgument(it) })
|
||||
// out of appLoaded scope
|
||||
this@startApplication.launch {
|
||||
val isInitialStart = configImportDeferred.await()
|
||||
// appLoaded not only provides starter, but also loads app, that's why it is here
|
||||
IdeStartupWizardCollector.logExperimentState()
|
||||
if (isInitialStart != null) {
|
||||
LoadingState.compareAndSetCurrentState(LoadingState.COMPONENTS_LOADED, LoadingState.APP_READY)
|
||||
val log = logDeferred.await()
|
||||
runCatching {
|
||||
span("startup wizard run") {
|
||||
runStartupWizard(isInitialStart = isInitialStart, app = ApplicationManager.getApplication())
|
||||
}
|
||||
}.getOrLogException(log)
|
||||
}
|
||||
executeApplicationStarter(starter = starter, args = args)
|
||||
}
|
||||
}
|
||||
|
||||
scheduleEnableCoroutineDumpAndJstack()
|
||||
|
||||
launch {
|
||||
// required for appStarter.prepareStart
|
||||
@@ -362,52 +302,31 @@ fun CoroutineScope.startApplication(args: List<String>,
|
||||
appStarter.start(InitAppContext(appRegistered = appRegisteredJob, appLoaded = appLoaded))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun enableNewUi(logDeferred: Deferred<Logger>) {
|
||||
if (System.getProperty("ide.experimental.ui") == null) {
|
||||
try {
|
||||
EarlyAccessRegistryManager.setAndFlush(mapOf("ide.experimental.ui" to "true"))
|
||||
}
|
||||
catch (e: CancellationException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
logDeferred.await().error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Volatile
|
||||
@JvmField
|
||||
internal var isInitialStart: CompletableDeferred<Boolean>? = null
|
||||
|
||||
private fun CoroutineScope.scheduleEnableCoroutineDumpAndJstack() {
|
||||
if (!System.getProperty("idea.enable.coroutine.dump", "true").toBoolean()) {
|
||||
return
|
||||
}
|
||||
|
||||
// out of appLoaded scope
|
||||
launch {
|
||||
span("coroutine debug probes init") {
|
||||
try {
|
||||
enableCoroutineDump()
|
||||
}
|
||||
catch (ignore: NoClassDefFoundError) {
|
||||
// if for some reason, the class loader has ByteBuddy in the classpath
|
||||
// (it is an error, and should be fixed - our dev mode and production behaves correctly)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
// starter is used later, but we need to wait for appLoaded completion
|
||||
val starter = appLoaded.await()
|
||||
|
||||
val isInitialStart = configImportDeferred.await()
|
||||
// appLoaded not only provides starter, but also loads app, that's why it is here
|
||||
launch {
|
||||
if (ConfigImportHelper.isFirstSession()) {
|
||||
IdeStartupWizardCollector.logExperimentState()
|
||||
}
|
||||
}
|
||||
span("coroutine jstack configuration") {
|
||||
JBR.getJstack()?.includeInfoFrom {
|
||||
"""
|
||||
$COROUTINE_DUMP_HEADER
|
||||
${dumpCoroutines(stripDump = false)}
|
||||
"""
|
||||
|
||||
if (isInitialStart != null) {
|
||||
LoadingState.compareAndSetCurrentState(LoadingState.COMPONENTS_LOADED, LoadingState.APP_READY)
|
||||
val log = logDeferred.await()
|
||||
runCatching {
|
||||
span("startup wizard run") {
|
||||
runStartupWizard(isInitialStart = isInitialStart, app = ApplicationManager.getApplication())
|
||||
}
|
||||
}.getOrLogException(log)
|
||||
}
|
||||
|
||||
executeApplicationStarter(starter = starter, args = args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,8 +393,9 @@ private fun CoroutineScope.scheduleLoadSystemLibsAndLogInfoAndInitMacApp(logDefe
|
||||
}
|
||||
}
|
||||
|
||||
fun processWindowsLauncherCommandLine(currentDirectory: String, args: Array<String>): Int =
|
||||
EXTERNAL_LISTENER.apply(currentDirectory, args)
|
||||
fun processWindowsLauncherCommandLine(currentDirectory: String, args: Array<String>): Int {
|
||||
return EXTERNAL_LISTENER.apply(currentDirectory, args)
|
||||
}
|
||||
|
||||
@get:Internal
|
||||
val isImplicitReadOnEDTDisabled: Boolean
|
||||
@@ -504,48 +424,6 @@ private suspend fun runPreAppClass(args: List<String>, classBeforeAppProperty: S
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun importConfig(args: List<String>,
|
||||
targetDirectoryToImportConfig: Path,
|
||||
log: Logger,
|
||||
appStarter: AppStarter,
|
||||
euaDocumentDeferred: Deferred<EndUserAgreement.Document?>,
|
||||
headlessAutoImport: Boolean = false) {
|
||||
if (headlessAutoImport) {
|
||||
// headless AppStarters are not notified about config import
|
||||
val veryFirstStartOnThisComputer = euaDocumentDeferred.await() != null
|
||||
withContext(RawSwingDispatcher) {
|
||||
try {
|
||||
ConfigImportHelper.importConfigsTo(veryFirstStartOnThisComputer, targetDirectoryToImportConfig, args, log, true)
|
||||
log.info("Automatic config import completed")
|
||||
}
|
||||
catch (e: UnsupportedOperationException) {
|
||||
log.info("Automatic config import is not possible", e)
|
||||
}
|
||||
}
|
||||
EarlyAccessRegistryManager.invalidate()
|
||||
IconLoader.clearCache()
|
||||
return
|
||||
}
|
||||
|
||||
span("screen reader checking") {
|
||||
runCatching {
|
||||
enableScreenReaderSupportIfNecessary()
|
||||
}.getOrLogException(log)
|
||||
}
|
||||
|
||||
span("config importing") {
|
||||
appStarter.beforeImportConfigs()
|
||||
|
||||
val veryFirstStartOnThisComputer = euaDocumentDeferred.await() != null
|
||||
withContext(RawSwingDispatcher) {
|
||||
ConfigImportHelper.importConfigsTo(veryFirstStartOnThisComputer, targetDirectoryToImportConfig, args, log)
|
||||
}
|
||||
appStarter.importFinished(targetDirectoryToImportConfig)
|
||||
EarlyAccessRegistryManager.invalidate()
|
||||
IconLoader.clearCache()
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.configureJavaUtilLogging(): Job {
|
||||
return launch(CoroutineName("console logger configuration")) {
|
||||
val rootLogger = java.util.logging.Logger.getLogger("")
|
||||
|
||||
@@ -29,8 +29,8 @@ fun isCoroutineDumpHeader(line: String): Boolean {
|
||||
return line == COROUTINE_DUMP_HEADER || line == COROUTINE_DUMP_HEADER_STRIPPED
|
||||
}
|
||||
|
||||
fun enableCoroutineDump() {
|
||||
runCatching {
|
||||
fun enableCoroutineDump(): Result<Unit> {
|
||||
return runCatching {
|
||||
DebugProbes.enableCreationStackTraces = false
|
||||
DebugProbes.install()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user