[run dashboard] IJPL-209900 Do not waste EDT time for preparing backend state for RPC transfer

It seems this computations are naturally async, makes sense to execute them later in the background

GitOrigin-RevId: 6e4b220eb01aef1df96c9884e4d4d3c3df800d20
This commit is contained in:
Nikita Katkov
2025-10-21 22:06:18 +00:00
committed by intellij-monorepo-bot
parent 0a26ce281d
commit 8495b2b110
2 changed files with 64 additions and 16 deletions
@@ -11,6 +11,7 @@ import com.intellij.execution.dashboard.RunDashboardServiceId
import com.intellij.ide.ui.icons.rpcId
import com.intellij.openapi.project.Project
import com.intellij.platform.execution.dashboard.splitApi.*
import com.intellij.platform.util.coroutines.childScope
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.*
@@ -28,6 +29,13 @@ internal class BackendRunDashboardManagerState(private val project: Project) {
private val sharedExcludedTypes = MutableStateFlow(emptySet<String>())
private val sharedStateUpdatesQueue = BackendRunDashboardUpdatesQueue(RunDashboardCoroutineScopeProvider.getInstance(project)
.cs.childScope("Backend run dashboard shared state updates"))
private fun scheduleSharedStateUpdate(update: SequentialComputationRequest) {
sharedStateUpdatesQueue.submit(update)
}
fun getLinkByServiceId(link: String, serviceId: RunDashboardServiceId): Runnable? {
return tagCallbacksByServiceId[serviceId]?.firstOrNull { linkDto -> linkDto.presentableText == link }?.callback
}
@@ -41,21 +49,27 @@ internal class BackendRunDashboardManagerState(private val project: Project) {
}
fun setServices(value: List<List<RunDashboardService>>) {
val flattenServices = value.flatten()
sharedServicesState.value = flattenServices.map { backendServiceModel ->
createServiceDto(backendServiceModel)
}
scheduleSharedStateUpdate {
val flattenServices = value.flatten()
sharedServicesState.value = flattenServices.map { backendServiceModel ->
createServiceDto(backendServiceModel)
}
val effectiveServicesSet = flattenServices.asSequence().map { it.uuid }.toSet()
tagCallbacksByServiceId.keys.retainAll(effectiveServicesSet)
val effectiveServicesSet = flattenServices.asSequence().map { it.uuid }.toSet()
tagCallbacksByServiceId.keys.retainAll(effectiveServicesSet)
}
}
fun setSettings(openRunningConfigInTab: Boolean) {
sharedSettings.value = RunDashboardSettingsDto(openRunningConfigInTab)
scheduleSharedStateUpdate {
sharedSettings.value = RunDashboardSettingsDto(openRunningConfigInTab)
}
}
fun fireExcludedTypesUpdated(excludedTypes: Set<String>) {
sharedExcludedTypes.value = excludedTypes
scheduleSharedStateUpdate {
sharedExcludedTypes.value = excludedTypes
}
}
fun getExcludedTypes(): Flow<Set<String>> {
@@ -63,11 +77,13 @@ internal class BackendRunDashboardManagerState(private val project: Project) {
}
fun fireStatusUpdated(backendService: RunDashboardService, persistedStatus: RunDashboardRunConfigurationStatus?) {
val effectiveStatus = when {
backendService.descriptor == null && persistedStatus != null -> persistedStatus
else -> RunDashboardRunConfigurationStatus.getStatus(backendService.descriptor)
scheduleSharedStateUpdate {
val effectiveStatus = when {
backendService.descriptor == null && persistedStatus != null -> persistedStatus
else -> RunDashboardRunConfigurationStatus.getStatus(backendService.descriptor)
}
sharedStatuses.tryEmit(ServiceStatusDto(backendService.uuid, effectiveStatus.id))
}
sharedStatuses.tryEmit(ServiceStatusDto(backendService.uuid, effectiveStatus.id))
}
fun getStatuses(): Flow<ServiceStatusDto> {
@@ -75,9 +91,11 @@ internal class BackendRunDashboardManagerState(private val project: Project) {
}
fun fireCustomizationUpdated(backendService: RunDashboardService, customizers: List<RunDashboardCustomizer>) {
val value = createCustomizationDto(backendService, customizers)
tagCallbacksByServiceId[backendService.uuid] = value.links
sharedServicesCustomizations.tryEmit(value)
scheduleSharedStateUpdate {
val value = createCustomizationDto(backendService, customizers)
tagCallbacksByServiceId[backendService.uuid] = value.links
sharedServicesCustomizations.tryEmit(value)
}
}
fun getCustomizations(): Flow<ServiceCustomizationDto> {
@@ -96,7 +114,9 @@ internal class BackendRunDashboardManagerState(private val project: Project) {
}
fun setConfigurationTypes(value: Set<String>) {
sharedConfigurationTypes.value = value
scheduleSharedStateUpdate {
sharedConfigurationTypes.value = value
}
}
fun getConfigurationTypes(): Flow<Set<String>> {
@@ -0,0 +1,28 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.execution.dashboard
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
internal typealias SequentialComputationRequest = suspend () -> Unit
internal class BackendRunDashboardUpdatesQueue(scope: CoroutineScope) {
private val channel = Channel<SequentialComputationRequest>(Channel.UNLIMITED)
init {
scope.launch {
for (request in channel) {
request()
}
}
}
fun submit(block: SequentialComputationRequest) {
channel.trySend(block)
}
fun close() {
channel.close()
}
}