From ee6b697c8c46c15cd9ed89bda09b5756dcd5b3ee Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 13 Sep 2019 07:49:12 +0200 Subject: [PATCH] unify impl of ServiceComponentAdapter and MyComponentAdapter once again (measurement, getImplementationClass) GitOrigin-RevId: 80571d5966297980e9549c22b934737a8c2bbdca --- .../serviceContainer/BaseComponentAdapter.kt | 35 ++++++++++++------- .../serviceContainer/MyComponentAdapter.kt | 20 ++++------- .../PlatformComponentManagerImpl.kt | 6 ++-- .../ServiceComponentAdapter.kt | 21 ++++------- 4 files changed, 39 insertions(+), 43 deletions(-) diff --git a/platform/service-container/src/com/intellij/serviceContainer/BaseComponentAdapter.kt b/platform/service-container/src/com/intellij/serviceContainer/BaseComponentAdapter.kt index 28e41a45718d..5105d18fcea3 100644 --- a/platform/service-container/src/com/intellij/serviceContainer/BaseComponentAdapter.kt +++ b/platform/service-container/src/com/intellij/serviceContainer/BaseComponentAdapter.kt @@ -2,9 +2,10 @@ package com.intellij.serviceContainer import com.intellij.diagnostic.LoadingPhase +import com.intellij.diagnostic.ParallelActivity import com.intellij.diagnostic.PluginException +import com.intellij.diagnostic.StartUpMeasurer import com.intellij.openapi.Disposable -import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.extensions.PluginDescriptor import com.intellij.openapi.extensions.PluginId import com.intellij.openapi.progress.ProgressIndicator @@ -15,12 +16,8 @@ import org.picocontainer.PicoVisitor internal abstract class BaseComponentAdapter(internal val componentManager: PlatformComponentManagerImpl, val pluginDescriptor: PluginDescriptor, - @field:Volatile protected var initializedInstance: Any?, + @field:Volatile private var initializedInstance: Any?, private var implementationClass: Class<*>?) : ComponentAdapter { - companion object { - private val LOG = logger() - } - private var initializing = false final override fun verify(container: PicoContainer) {} @@ -63,21 +60,19 @@ internal abstract class BaseComponentAdapter(internal val componentManager: Plat return getInstance(componentManager) } - @Suppress("UNCHECKED_CAST") fun getInstance(componentManager: PlatformComponentManagerImpl, createIfNeeded: Boolean = true, indicator: ProgressIndicator? = null): T? { // could be called during some component.dispose() call, in this case we don't attempt to instantiate + @Suppress("UNCHECKED_CAST") var instance = initializedInstance as T? if (instance != null || !createIfNeeded) { return instance } - if (componentManager.isContainerDisposedOrDisposeInProgress()) { - throw PluginException("Cannot create ${toString()} because service container is already disposed (container=${componentManager}", pluginId) - } - LoadingPhase.COMPONENT_REGISTERED.assertAtLeast() + checkContainerIsActive(componentManager) synchronized(this) { + @Suppress("UNCHECKED_CAST") instance = initializedInstance as T? if (instance != null) { return instance @@ -89,7 +84,13 @@ internal abstract class BaseComponentAdapter(internal val componentManager: Plat try { initializing = true - instance = doCreateInstance(componentManager, indicator) + + val startTime = StartUpMeasurer.getCurrentTime() + val implementationClass = getImplementationClass() + @Suppress("UNCHECKED_CAST") + instance = doCreateInstance(componentManager, implementationClass as Class, indicator) + getParallelActivity()?.record(startTime, implementationClass, componentManager.getActivityLevel(), pluginId.idString) + initializedInstance = instance return instance } @@ -99,7 +100,15 @@ internal abstract class BaseComponentAdapter(internal val componentManager: Plat } } - protected abstract fun doCreateInstance(componentManager: PlatformComponentManagerImpl, indicator: ProgressIndicator?): T + private fun checkContainerIsActive(componentManager: PlatformComponentManagerImpl) { + if (componentManager.isContainerDisposedOrDisposeInProgress()) { + throw PluginException("Cannot create ${toString()} because service container is already disposed (container=${componentManager}", pluginId) + } + } + + protected abstract fun getParallelActivity(): ParallelActivity? + + protected abstract fun doCreateInstance(componentManager: PlatformComponentManagerImpl, implementationClass: Class, indicator: ProgressIndicator?): T @Synchronized fun replaceInstance(instance: T, parentDisposable: Disposable?): T? { diff --git a/platform/service-container/src/com/intellij/serviceContainer/MyComponentAdapter.kt b/platform/service-container/src/com/intellij/serviceContainer/MyComponentAdapter.kt index 9300061322d5..cc48ce563414 100644 --- a/platform/service-container/src/com/intellij/serviceContainer/MyComponentAdapter.kt +++ b/platform/service-container/src/com/intellij/serviceContainer/MyComponentAdapter.kt @@ -1,7 +1,6 @@ // Copyright 2000-2019 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.serviceContainer -import com.intellij.diagnostic.Activity import com.intellij.diagnostic.ParallelActivity import com.intellij.openapi.Disposable import com.intellij.openapi.components.BaseComponent @@ -18,20 +17,16 @@ internal class MyComponentAdapter(private val componentKey: Class<*>, val isWorkspaceComponent: Boolean = false) : BaseComponentAdapter(componentManager, pluginDescriptor, null, implementationClass) { override fun getComponentKey() = componentKey - private fun createMeasureActivity(componentManager: PlatformComponentManagerImpl): Activity? { - if (componentManager.activityNamePrefix() == null) { - return null + override fun getParallelActivity(): ParallelActivity? { + return when { + componentManager.activityNamePrefix() == null -> null + else -> ParallelActivity.COMPONENT } - - val level = componentManager.getActivityLevel() - return ParallelActivity.COMPONENT.start(implementationClassName, level, pluginId.idString) } - override fun doCreateInstance(componentManager: PlatformComponentManagerImpl, indicator: ProgressIndicator?): T { + override fun doCreateInstance(componentManager: PlatformComponentManagerImpl, implementationClass: Class, indicator: ProgressIndicator?): T { try { - val activity = createMeasureActivity(componentManager) - @Suppress("UNCHECKED_CAST") - val instance = componentManager.instantiateClassWithConstructorInjection(getImplementationClass() as Class, componentKey, pluginId) + val instance = componentManager.instantiateClassWithConstructorInjection(implementationClass, componentKey, pluginId) if (instance is Disposable) { Disposer.register(componentManager, instance) } @@ -40,8 +35,6 @@ internal class MyComponentAdapter(private val componentKey: Class<*>, if (instance is BaseComponent) { (instance as BaseComponent).initComponent() } - - activity?.end() return instance } catch (e: ProcessCanceledException) { @@ -51,7 +44,6 @@ internal class MyComponentAdapter(private val componentKey: Class<*>, componentManager.handleInitComponentError(t, getComponentKey().name, pluginId) throw t } - } override fun toString() = "ComponentAdapter(key=${getComponentKey()}, implementation=${componentImplementation}, plugin=$pluginId)" diff --git a/platform/service-container/src/com/intellij/serviceContainer/PlatformComponentManagerImpl.kt b/platform/service-container/src/com/intellij/serviceContainer/PlatformComponentManagerImpl.kt index d051a6bd3556..f2f931cfe818 100644 --- a/platform/service-container/src/com/intellij/serviceContainer/PlatformComponentManagerImpl.kt +++ b/platform/service-container/src/com/intellij/serviceContainer/PlatformComponentManagerImpl.kt @@ -14,6 +14,7 @@ import com.intellij.openapi.components.* import com.intellij.openapi.components.impl.ComponentManagerImpl import com.intellij.openapi.components.impl.stores.IComponentStore import com.intellij.openapi.diagnostic.ControlFlowException +import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.extensions.* import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl import com.intellij.openapi.progress.ProcessCanceledException @@ -38,6 +39,8 @@ import java.util.* import java.util.concurrent.CompletableFuture import java.util.concurrent.ConcurrentMap +internal val LOG = logger() + abstract class PlatformComponentManagerImpl @JvmOverloads constructor(internal val parent: ComponentManager?, setExtensionsRootArea: Boolean = parent == null) : ComponentManagerImpl(parent), LazyListenerCreator { companion object { private val constructorParameterResolver = ConstructorParameterResolver() @@ -622,8 +625,7 @@ abstract class PlatformComponentManagerImpl @JvmOverloads constructor(internal v return CompletableFuture.allOf(*futures.toTypedArray()) } - // todo check is it safe to use this implementation in `isContainerDisposed` (for now, old behaviour is not changed) - // if it is safe, this method is not needed + // todo fix tests to use this implementation in `isContainerDisposed` fun isContainerDisposedOrDisposeInProgress(): Boolean { return myContainerState.ordinal >= ContainerState.DISPOSE_IN_PROGRESS.ordinal } diff --git a/platform/service-container/src/com/intellij/serviceContainer/ServiceComponentAdapter.kt b/platform/service-container/src/com/intellij/serviceContainer/ServiceComponentAdapter.kt index beefd4ae6f6d..ae6b44075a52 100644 --- a/platform/service-container/src/com/intellij/serviceContainer/ServiceComponentAdapter.kt +++ b/platform/service-container/src/com/intellij/serviceContainer/ServiceComponentAdapter.kt @@ -2,11 +2,9 @@ package com.intellij.serviceContainer import com.intellij.diagnostic.ParallelActivity -import com.intellij.diagnostic.StartUpMeasurer import com.intellij.openapi.Disposable import com.intellij.openapi.components.PersistentStateComponent import com.intellij.openapi.components.ServiceDescriptor -import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.extensions.PluginDescriptor import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressManager @@ -14,8 +12,6 @@ import com.intellij.openapi.util.Disposer import com.intellij.util.io.storage.HeavyProcessLatch import com.intellij.util.pico.AssignableToComponentAdapter -internal val LOG = logger() - internal class ServiceComponentAdapter(val descriptor: ServiceDescriptor, pluginDescriptor: PluginDescriptor, componentManager: PlatformComponentManagerImpl, @@ -26,11 +22,13 @@ internal class ServiceComponentAdapter(val descriptor: ServiceDescriptor, override fun getComponentKey(): String = descriptor.getInterface() - override fun doCreateInstance(componentManager: PlatformComponentManagerImpl, indicator: ProgressIndicator?): T { + override fun getParallelActivity() = ParallelActivity.SERVICE + + override fun doCreateInstance(componentManager: PlatformComponentManagerImpl, implementationClass: Class, indicator: ProgressIndicator?): T { if (LOG.isDebugEnabled) { val app = componentManager.getApplication() if (app != null && app.isWriteAccessAllowed && !app.isUnitTestMode && - PersistentStateComponent::class.java.isAssignableFrom(getImplementationClass())) { + PersistentStateComponent::class.java.isAssignableFrom(implementationClass)) { LOG.warn(Throwable("Getting service from write-action leads to possible deadlock. Service implementation ${implementationClassName}")) } } @@ -38,29 +36,24 @@ internal class ServiceComponentAdapter(val descriptor: ServiceDescriptor, // heavy to prevent storages from flushing and blocking FS HeavyProcessLatch.INSTANCE.processStarted(implementationClassName).use { if (ProgressManager.getGlobalProgressIndicator() == null) { - return createAndInitialize(componentManager) + return createAndInitialize(componentManager, implementationClass) } else { var instance: T? = null ProgressManager.getInstance().executeNonCancelableSection { - instance = createAndInitialize(componentManager) + instance = createAndInitialize(componentManager, implementationClass) } return instance!! } } } - private fun createAndInitialize(componentManager: PlatformComponentManagerImpl): T { - val startTime = StartUpMeasurer.getCurrentTime() - @Suppress("UNCHECKED_CAST") - val implementationClass = getImplementationClass() as Class + private fun createAndInitialize(componentManager: PlatformComponentManagerImpl, implementationClass: Class): T { val instance = componentManager.instantiateClassWithConstructorInjection(implementationClass, componentKey, pluginId) if (instance is Disposable) { Disposer.register(componentManager, instance) } - componentManager.initializeComponent(instance, descriptor) - ParallelActivity.SERVICE.record(startTime, implementationClass, componentManager.getActivityLevel(), pluginId.idString) return instance }