unify impl of ServiceComponentAdapter and MyComponentAdapter once again (measurement, getImplementationClass)

GitOrigin-RevId: 80571d5966297980e9549c22b934737a8c2bbdca
This commit is contained in:
Vladimir Krivosheev
2019-09-13 07:12:19 +00:00
committed by intellij-monorepo-bot
parent 6b7b312220
commit ee6b697c8c
4 changed files with 39 additions and 43 deletions
@@ -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<BaseComponentAdapter>()
}
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 <T : Any> 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<T>, 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 <T : Any> 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 <T : Any> doCreateInstance(componentManager: PlatformComponentManagerImpl, implementationClass: Class<T>, indicator: ProgressIndicator?): T
@Synchronized
fun <T : Any> replaceInstance(instance: T, parentDisposable: Disposable?): T? {
@@ -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 <T : Any> doCreateInstance(componentManager: PlatformComponentManagerImpl, indicator: ProgressIndicator?): T {
override fun <T : Any> doCreateInstance(componentManager: PlatformComponentManagerImpl, implementationClass: Class<T>, indicator: ProgressIndicator?): T {
try {
val activity = createMeasureActivity(componentManager)
@Suppress("UNCHECKED_CAST")
val instance = componentManager.instantiateClassWithConstructorInjection(getImplementationClass() as Class<T>, 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)"
@@ -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<PlatformComponentManagerImpl>()
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
}
@@ -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<ServiceComponentAdapter>()
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 <T : Any> doCreateInstance(componentManager: PlatformComponentManagerImpl, indicator: ProgressIndicator?): T {
override fun getParallelActivity() = ParallelActivity.SERVICE
override fun <T : Any> doCreateInstance(componentManager: PlatformComponentManagerImpl, implementationClass: Class<T>, 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 <T : Any> createAndInitialize(componentManager: PlatformComponentManagerImpl): T {
val startTime = StartUpMeasurer.getCurrentTime()
@Suppress("UNCHECKED_CAST")
val implementationClass = getImplementationClass() as Class<T>
private fun <T : Any> createAndInitialize(componentManager: PlatformComponentManagerImpl, implementationClass: Class<T>): 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
}