mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
IJPL-234844 Dump WSM to log directory on every WSM update IJ-CR-193116
(cherry picked from commit b854cb31be3b9f76ba91765833487b6ddefe5bfa) GitOrigin-RevId: 094b577e4a261e24e9b3eecfe98e98c5af0d2cf9
This commit is contained in:
committed by
intellij-monorepo-bot
parent
23813d84e5
commit
24f2ff56aa
@@ -28,8 +28,8 @@ import com.intellij.workspaceModel.ide.impl.GlobalWorkspaceModel
|
||||
import com.intellij.workspaceModel.ide.impl.WorkspaceModelImpl
|
||||
import com.intellij.workspaceModel.ide.impl.jps.serialization.JpsProjectModelSynchronizer
|
||||
import com.intellij.workspaceModel.ide.impl.jpsMetrics
|
||||
import com.intellij.workspaceModel.ide.impl.jsonDump.DumpWorkspaceEntitiesWsmChangeListener
|
||||
import com.intellij.workspaceModel.ide.impl.legacyBridge.library.ProjectLibraryTableBridgeImpl
|
||||
import com.intellij.workspaceModel.ide.impl.legacyBridge.project.ProjectRootManagerBridge
|
||||
import com.intellij.workspaceModel.ide.legacyBridge.ModuleDependencyIndex
|
||||
import io.opentelemetry.api.metrics.Meter
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
@@ -57,6 +57,7 @@ private fun setupOpenTelemetryReporting(meter: Meter) {
|
||||
class ModuleBridgeLoaderService : InitProjectActivity {
|
||||
override suspend fun run(project: Project) {
|
||||
coroutineScope {
|
||||
project.serviceAsync<DumpWorkspaceEntitiesWsmChangeListener>()
|
||||
val projectModelSynchronizer = project.serviceAsync<JpsProjectModelSynchronizer>()
|
||||
val workspaceModel = project.serviceAsync<WorkspaceModel>() as WorkspaceModelImpl
|
||||
|
||||
|
||||
@@ -3,8 +3,18 @@ package com.intellij.workspaceModel.ide.impl.jsonDump
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.DumbAwareAction
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.platform.backend.workspace.WorkspaceModelChangeListener
|
||||
import com.intellij.platform.backend.workspace.WorkspaceModelTopics
|
||||
import com.intellij.platform.backend.workspace.workspaceModel
|
||||
import com.intellij.platform.workspace.storage.VersionedStorageChange
|
||||
import com.intellij.util.PathUtil
|
||||
import com.intellij.workspaceModel.ide.impl.WorkspaceModelImpl
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
@ApiStatus.Internal
|
||||
@@ -20,6 +30,25 @@ class DumpWorkspaceEntitiesToClipboardAction : DumbAwareAction() {
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
@Service(Service.Level.PROJECT)
|
||||
class DumpWorkspaceEntitiesWsmChangeListener(val project: Project, val scope: CoroutineScope) {
|
||||
init {
|
||||
project.messageBus.connect(project).subscribe(WorkspaceModelTopics.CHANGED, object : WorkspaceModelChangeListener {
|
||||
override fun changed(event: VersionedStorageChange) {
|
||||
if (!Registry.`is`("ide.workspace.model.dump.on.every.wsm.update")){
|
||||
return
|
||||
}
|
||||
|
||||
val version = (project.workspaceModel as WorkspaceModelImpl).entityStorage.version
|
||||
val fileName = "${System.currentTimeMillis()}-workspace-model-dump-version-${PathUtil.suggestFileName(project.name)}.${project.locationHash}-$version"
|
||||
project.service<WorkspaceModelJsonDumpService>()
|
||||
.dumpWorkspaceEntitiesToLogFileAsJson(fileName, event.storageAfter, openFileInEditor = false)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
class DumpWorkspaceEntitiesToLogAction : DumbAwareAction() {
|
||||
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.intellij.openapi.vfs.writeText
|
||||
import com.intellij.platform.backend.workspace.workspaceModel
|
||||
import com.intellij.platform.ide.progress.withBackgroundProgress
|
||||
import com.intellij.platform.util.progress.reportSequentialProgress
|
||||
import com.intellij.platform.workspace.storage.EntityStorage
|
||||
import com.intellij.platform.workspace.storage.WorkspaceEntityWithSymbolicId
|
||||
import com.intellij.workspaceModel.ide.impl.WorkspaceModelIdeBundle
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -47,13 +49,12 @@ class WorkspaceModelJsonDumpService(private val project: Project, private val co
|
||||
prettyPrintIndent = " "
|
||||
}
|
||||
|
||||
private val logFileName = "workspace-model-dump.json"
|
||||
|
||||
suspend fun getWorkspaceEntitiesAsJsonArray(): JsonArray {
|
||||
val snapshot = project.workspaceModel.currentSnapshot
|
||||
private val logFileName = "workspace-model-dump"
|
||||
|
||||
suspend fun getWorkspaceEntitiesAsJsonArray(snapshot: EntityStorage? = null): JsonArray {
|
||||
val snapshot = snapshot ?: project.workspaceModel.currentSnapshot
|
||||
val wsmSerializers = WorkspaceModelSerializers()
|
||||
val rootEntities = snapshot.allUniqueEntities().rootEntitiesClasses().toList()
|
||||
val rootEntities = snapshot.allUniqueEntities().rootEntitiesClasses().toList().sortedBy { it.simpleName }
|
||||
|
||||
return withBackgroundProgress(project, WorkspaceModelIdeBundle.message("progress.title.dumping.workspace.entities.json.to.clipboard")) {
|
||||
reportSequentialProgress(rootEntities.size) { reporter ->
|
||||
@@ -62,7 +63,7 @@ class WorkspaceModelJsonDumpService(private val project: Project, private val co
|
||||
reporter.itemStep(rootEntityClass.name)
|
||||
addJsonObject {
|
||||
put("rootEntityName", rootEntityClass.simpleName)
|
||||
val entities = snapshot.entities(rootEntityClass).toList()
|
||||
val entities = snapshot.entities(rootEntityClass).toList().sortedBy { if (it is WorkspaceEntityWithSymbolicId) it.symbolicId.presentableName else it.toString() }
|
||||
put("rootEntitiesCount", entities.size)
|
||||
putJsonArray("entities") {
|
||||
for ((i, entity) in entities.withIndex()) {
|
||||
@@ -97,7 +98,8 @@ class WorkspaceModelJsonDumpService(private val project: Project, private val co
|
||||
}
|
||||
}
|
||||
|
||||
fun dumpWorkspaceEntitiesToLogFileAsJson() {
|
||||
fun dumpWorkspaceEntitiesToLogFileAsJson(name: String = logFileName, snapshot: EntityStorage? = null, openFileInEditor: Boolean = true) {
|
||||
val fileName = "$name.json"
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
val logDirectory2 = LoggerFactory.getLogFilePath().parent?.let {
|
||||
LocalFileSystem.getInstance().refreshAndFindFileByNioFile(it)
|
||||
@@ -108,14 +110,16 @@ class WorkspaceModelJsonDumpService(private val project: Project, private val co
|
||||
Notifications.Bus.notify(Notification(groupAndTitle, groupAndTitle, content, NotificationType.INFORMATION))
|
||||
return@launch
|
||||
}
|
||||
val jsonEntities = getWorkspaceEntitiesAsJsonArray()
|
||||
val jsonEntities = getWorkspaceEntitiesAsJsonArray(snapshot)
|
||||
val serializedEntitiesString = json.encodeToString(jsonEntities)
|
||||
val wsmDumpFile = edtWriteAction {
|
||||
logDirectory2.findChild(logFileName)?.delete(this)
|
||||
val wsmDumpFile = logDirectory2.createChildData(this, logFileName)
|
||||
logDirectory2.findChild(fileName)?.delete(this)
|
||||
val wsmDumpFile = logDirectory2.createChildData(this, fileName)
|
||||
wsmDumpFile.writeText(serializedEntitiesString)
|
||||
VfsUtil.markDirtyAndRefresh(true, false, false, wsmDumpFile)
|
||||
openDumpInEditor(wsmDumpFile)
|
||||
if (openFileInEditor) {
|
||||
openDumpInEditor(wsmDumpFile)
|
||||
}
|
||||
wsmDumpFile
|
||||
}
|
||||
LOG.info("Workspace model was dumped to ${wsmDumpFile.canonicalPath}")
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
description="Enable workspace model checking for accessing bridges from WSM listeners"/>
|
||||
<registryKey key="ide.workspace.model.per.environment.model.separation" defaultValue="true" restartRequired="true"
|
||||
description="Enable existence of multiple workspace models, one per each isolated environment"/>
|
||||
<registryKey key="ide.workspace.model.dump.on.every.wsm.update" defaultValue="false" restartRequired="false"
|
||||
description="Dump workspace model to log directory on every WSM update"/>
|
||||
<registryKey key="use.workspace.file.index.for.partial.scanning" defaultValue="true" restartRequired="true"
|
||||
description="If enabled, relies on events from WorkspaceFileIndex for partial scanning"/>
|
||||
<registryKey key="create.coroutines.for.wfi.events.processing" defaultValue="true" restartRequired="false"
|
||||
|
||||
@@ -337,13 +337,7 @@ open class WorkspaceModelImpl : WorkspaceModelInternal {
|
||||
updatesCounter.incrementAndGet()
|
||||
}
|
||||
|
||||
log.debug("Project model updated silently to version ${entityStorage.pointer.version} in $generalTime ms: $description")
|
||||
if (generalTime > 1000) {
|
||||
log.info("Project model update details: Updater code: $updateTimeMillis ms, To snapshot: $toSnapshotTimeMillis m")
|
||||
}
|
||||
else {
|
||||
log.debug { "Project model update details: Updater code: $updateTimeMillis ms, To snapshot: $toSnapshotTimeMillis m" }
|
||||
}
|
||||
log.info("Project model updated silently to version ${entityStorage.pointer.version} in $generalTime ms: $description")
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user