mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[wsm] IJPL-178632 Extract common logic into GlobalWorkspaceModels
Refactors `GlobalWorkspaceModel` by extracting the common part into `GlobalWorkspaceModels`, shared by all environment-specific implementations. Prepares the codebase for clearer boundaries between environments. GitOrigin-RevId: 0e9dbe872ce4772ddd5c59fa082bacb2ba3d3e64
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5043d94087
commit
6205dc5668
+36
-13
@@ -46,9 +46,35 @@ import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
@OptIn(EntityStorageInstrumentationApi::class)
|
||||
@ApiStatus.Internal
|
||||
class GlobalWorkspaceModels internal constructor() {
|
||||
internal var virtualFileManager: VirtualFileUrlManager = IdeVirtualFileUrlManagerImpl()
|
||||
|
||||
internal val globalWorkspaceModelCache = GlobalWorkspaceModelCache.getInstance()?.apply {
|
||||
setVirtualFileUrlManager(virtualFileManager)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns instance of [VirtualFileUrlManager] which should be used to create [VirtualFileUrl] instances to be stored in entities added in
|
||||
* the global application-level storage.
|
||||
* It's important not to use this function for entities stored in the main [WorkspaceModel][WorkspaceModel]
|
||||
* storage, because this would create a memory leak: these instances won't be removed when the project is closed.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
fun getVirtualFileUrlManager(): VirtualFileUrlManager = virtualFileManager
|
||||
|
||||
@TestOnly
|
||||
fun resetVirtualFileUrlManager() {
|
||||
virtualFileManager = IdeVirtualFileUrlManagerImpl()
|
||||
globalWorkspaceModelCache?.setVirtualFileUrlManager(virtualFileManager)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(EntityStorageInstrumentationApi::class)
|
||||
@ApiStatus.Internal
|
||||
class GlobalWorkspaceModel internal constructor(
|
||||
private val globalWorkspaceModels: GlobalWorkspaceModels,
|
||||
/**
|
||||
* Despite the prefix `Global`, the IDE can have multiple workspace models per isolated environment, such as WSL and Docker containers.
|
||||
*
|
||||
@@ -68,11 +94,6 @@ class GlobalWorkspaceModel internal constructor(
|
||||
|
||||
// Marker indicating that changes came from global storage
|
||||
internal var isFromGlobalWorkspaceModel: Boolean = false
|
||||
private var virtualFileManager: VirtualFileUrlManager = IdeVirtualFileUrlManagerImpl()
|
||||
private val globalWorkspaceModelCache = GlobalWorkspaceModelCache.getInstance()?.apply {
|
||||
setVirtualFileUrlManager(virtualFileManager)
|
||||
registerCachePartition(internalEnvironmentName)
|
||||
}
|
||||
private val globalEntitiesFilter = { entitySource: EntitySource -> entitySource is GlobalStorageEntitySource }
|
||||
|
||||
val entityStorage: VersionedEntityStorageImpl
|
||||
@@ -88,7 +109,9 @@ class GlobalWorkspaceModel internal constructor(
|
||||
init {
|
||||
LOG.debug { "Loading global workspace model" }
|
||||
|
||||
val cache = globalWorkspaceModelCache
|
||||
val cache = globalWorkspaceModels.globalWorkspaceModelCache?.apply {
|
||||
registerCachePartition(internalEnvironmentName)
|
||||
}
|
||||
val mutableEntityStorage: MutableEntityStorage = when {
|
||||
cache != null -> {
|
||||
val activity = StartUpMeasurer.startActivity("global cache loading")
|
||||
@@ -112,7 +135,7 @@ class GlobalWorkspaceModel internal constructor(
|
||||
entityStorage = VersionedEntityStorageImpl(ImmutableEntityStorage.empty())
|
||||
|
||||
val callback = JpsGlobalModelSynchronizer.getInstance()
|
||||
.apply { setVirtualFileUrlManager(virtualFileManager) }
|
||||
.apply { setVirtualFileUrlManager(globalWorkspaceModels.virtualFileManager) }
|
||||
.loadInitialState(internalEnvironmentName, mutableEntityStorage, entityStorage, loadedFromCache)
|
||||
val changes = (mutableEntityStorage as MutableEntityStorageInstrumentation).collectChanges()
|
||||
entityStorage.replace(mutableEntityStorage.toSnapshot(), changes, mutableEntityStorage.collectSymbolicEntityIdsChanges(), {}, {})
|
||||
@@ -175,12 +198,11 @@ class GlobalWorkspaceModel internal constructor(
|
||||
* storage, because this would create a memory leak: these instances won't be removed when the project is closed.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
fun getVirtualFileUrlManager(): VirtualFileUrlManager = virtualFileManager
|
||||
fun getVirtualFileUrlManager(): VirtualFileUrlManager = globalWorkspaceModels.virtualFileManager
|
||||
|
||||
@TestOnly
|
||||
fun resetVirtualFileUrlManager() {
|
||||
virtualFileManager = IdeVirtualFileUrlManagerImpl()
|
||||
globalWorkspaceModelCache?.setVirtualFileUrlManager(virtualFileManager)
|
||||
globalWorkspaceModels.resetVirtualFileUrlManager()
|
||||
}
|
||||
|
||||
@RequiresWriteLock
|
||||
@@ -206,7 +228,7 @@ class GlobalWorkspaceModel internal constructor(
|
||||
|
||||
GlobalEntityBridgeAndEventHandler.getAllGlobalEntityHandlers(eelMachine).forEach { it.handleChangedEvents(change) }
|
||||
|
||||
globalWorkspaceModelCache?.scheduleCacheSave()
|
||||
globalWorkspaceModels.globalWorkspaceModelCache?.scheduleCacheSave()
|
||||
isFromGlobalWorkspaceModel = true
|
||||
for (project in ProjectManager.getInstance().openProjects) {
|
||||
if (project.isDisposed || project.getEelDescriptor().machine != eelMachine) {
|
||||
@@ -249,7 +271,7 @@ class GlobalWorkspaceModel internal constructor(
|
||||
|
||||
filteredProject = sourceProject
|
||||
val entitiesCopyAtBuilder = copyEntitiesToEmptyStorage(WorkspaceModel.getInstance(sourceProject).currentSnapshot,
|
||||
virtualFileManager)
|
||||
globalWorkspaceModels.virtualFileManager)
|
||||
updateModel("Sync entities from project ${sourceProject.name} with global storage") { builder ->
|
||||
builder.replaceBySource(globalEntitiesFilter, entitiesCopyAtBuilder)
|
||||
}
|
||||
@@ -401,6 +423,7 @@ private fun JpsGlobalFileEntitySource.copy(manager: VirtualFileUrlManager): JpsG
|
||||
@VisibleForTesting
|
||||
@Service(Service.Level.APP)
|
||||
class GlobalWorkspaceModelRegistry {
|
||||
private val globalWorkspaceModels: GlobalWorkspaceModels by lazy { GlobalWorkspaceModels() }
|
||||
private val environmentToModel = ConcurrentHashMap<EelMachine, GlobalWorkspaceModel>()
|
||||
|
||||
fun getGlobalModel(eelMachine: EelMachine): GlobalWorkspaceModel {
|
||||
@@ -415,7 +438,7 @@ class GlobalWorkspaceModelRegistry {
|
||||
?: throw IllegalArgumentException("Descriptor $protectedMachine must be registered before using in Workspace Model")
|
||||
InternalEnvironmentName.of(name)
|
||||
}
|
||||
return environmentToModel.computeIfAbsent(protectedMachine) { GlobalWorkspaceModel(protectedMachine, internalEnvironmentName) }
|
||||
return environmentToModel.computeIfAbsent(protectedMachine) { GlobalWorkspaceModel(globalWorkspaceModels, protectedMachine, internalEnvironmentName) }
|
||||
}
|
||||
|
||||
fun getGlobalModelByEnvironmentName(name: InternalEnvironmentName): GlobalWorkspaceModel {
|
||||
|
||||
Reference in New Issue
Block a user