From d6875bb846b52a7f0eb0d21c088fe99ebd8ba5f5 Mon Sep 17 00:00:00 2001 From: Rival Abdrakhmanov Date: Fri, 19 Jul 2024 13:04:07 +0200 Subject: [PATCH] Get the focused project from the context while restarting/stopping a resource --- .../dashboard/RestartDebugResourceAction.kt | 94 ++++++++++++++----- .../dashboard/RestartResourceAction.kt | 94 ++++++++++++++----- .../actions/dashboard/StopResourceAction.kt | 94 ++++++++++++++----- .../aspire/sessionHost/SessionManager.kt | 9 ++ 4 files changed, 216 insertions(+), 75 deletions(-) diff --git a/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/RestartDebugResourceAction.kt b/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/RestartDebugResourceAction.kt index 39cfefa7..b95f52f8 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/RestartDebugResourceAction.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/RestartDebugResourceAction.kt @@ -1,12 +1,17 @@ +@file:Suppress("UnstableApiUsage") + package me.rafaelldi.aspire.actions.dashboard import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.progress.currentThreadCoroutineScope import com.intellij.platform.ide.progress.withBackgroundProgress +import com.intellij.workspaceModel.ide.toPath +import com.jetbrains.rider.projectView.workspace.containingProjectEntity +import com.jetbrains.rider.projectView.workspace.getProjectModelEntity import kotlinx.coroutines.launch import me.rafaelldi.aspire.AspireBundle -import me.rafaelldi.aspire.AspireService import me.rafaelldi.aspire.generated.ResourceState import me.rafaelldi.aspire.generated.ResourceType import me.rafaelldi.aspire.sessionHost.SessionManager @@ -17,17 +22,31 @@ import me.rafaelldi.aspire.util.ASPIRE_RESOURCE_UID class RestartDebugResourceAction : AnAction() { override fun actionPerformed(event: AnActionEvent) { val project = event.project ?: return - val resourceUid = event.getData(ASPIRE_RESOURCE_UID) ?: return - val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) ?: return - val resourceState = event.getData(ASPIRE_RESOURCE_STATE) ?: return + val resourceUid = event.getData(ASPIRE_RESOURCE_UID) - if (resourceType != ResourceType.Project || resourceState != ResourceState.Running) { - return - } + if (resourceUid != null) { + val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) + val resourceState = event.getData(ASPIRE_RESOURCE_STATE) - AspireService.getInstance(project).scope.launch { - withBackgroundProgress(project, AspireBundle.message("progress.restart.resource")) { - SessionManager.getInstance(project).restartResource(resourceUid, true) + if (resourceType == ResourceType.Project && resourceState == ResourceState.Running) { + currentThreadCoroutineScope().launch { + withBackgroundProgress(project, AspireBundle.message("progress.stop.resource")) { + SessionManager.getInstance(project).restartResource(resourceUid, true) + } + } + } + } else { + val projectEntity = event.dataContext + .getProjectModelEntity(true) + ?.containingProjectEntity() + ?: return + val projectPath = projectEntity.url?.toPath() ?: return + val resourceId = SessionManager.getInstance(project).getResourceIdByProject(projectPath) ?: return + + currentThreadCoroutineScope().launch { + withBackgroundProgress(project, AspireBundle.message("progress.stop.resource")) { + SessionManager.getInstance(project).restartResource(resourceId, true) + } } } } @@ -40,24 +59,49 @@ class RestartDebugResourceAction : AnAction() { } val resourceUid = event.getData(ASPIRE_RESOURCE_UID) - val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) - val resourceState = event.getData(ASPIRE_RESOURCE_STATE) - if (resourceUid == null || resourceType == null || resourceState == null) { - event.presentation.isEnabledAndVisible = false - return - } - if (resourceType != ResourceType.Project || resourceState != ResourceState.Running) { - event.presentation.isEnabledAndVisible = false - return - } + if (resourceUid != null) { + val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) + val resourceState = event.getData(ASPIRE_RESOURCE_STATE) - if (!SessionManager.getInstance(project).isResourceRunning(resourceUid)) { - event.presentation.isEnabledAndVisible = false - return - } + if (resourceType != ResourceType.Project || resourceState != ResourceState.Running) { + event.presentation.isEnabledAndVisible = false + return + } + + if (!SessionManager.getInstance(project).isResourceRunning(resourceUid)) { + event.presentation.isEnabledAndVisible = false + return + } + + event.presentation.isEnabledAndVisible = true + } else { + val projectEntity = event.dataContext.getProjectModelEntity(true)?.containingProjectEntity() + + if (projectEntity == null) { + event.presentation.isEnabledAndVisible = false + return + } - event.presentation.isEnabledAndVisible = true + val projectPath = projectEntity.url?.toPath() + if (projectPath == null) { + event.presentation.isEnabledAndVisible = false + return + } + + val resourceId = SessionManager.getInstance(project).getResourceIdByProject(projectPath) + if (resourceId == null) { + event.presentation.isEnabledAndVisible = false + return + } + + if (!SessionManager.getInstance(project).isResourceRunning(resourceId)) { + event.presentation.isEnabledAndVisible = false + return + } + + event.presentation.isEnabledAndVisible = true + } } override fun getActionUpdateThread() = ActionUpdateThread.EDT diff --git a/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/RestartResourceAction.kt b/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/RestartResourceAction.kt index af61b623..4985b796 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/RestartResourceAction.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/RestartResourceAction.kt @@ -1,12 +1,17 @@ +@file:Suppress("UnstableApiUsage") + package me.rafaelldi.aspire.actions.dashboard import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.progress.currentThreadCoroutineScope import com.intellij.platform.ide.progress.withBackgroundProgress +import com.intellij.workspaceModel.ide.toPath +import com.jetbrains.rider.projectView.workspace.containingProjectEntity +import com.jetbrains.rider.projectView.workspace.getProjectModelEntity import kotlinx.coroutines.launch import me.rafaelldi.aspire.AspireBundle -import me.rafaelldi.aspire.AspireService import me.rafaelldi.aspire.generated.ResourceState import me.rafaelldi.aspire.generated.ResourceType import me.rafaelldi.aspire.sessionHost.SessionManager @@ -17,17 +22,31 @@ import me.rafaelldi.aspire.util.ASPIRE_RESOURCE_UID class RestartResourceAction : AnAction() { override fun actionPerformed(event: AnActionEvent) { val project = event.project ?: return - val resourceUid = event.getData(ASPIRE_RESOURCE_UID) ?: return - val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) ?: return - val resourceState = event.getData(ASPIRE_RESOURCE_STATE) ?: return + val resourceUid = event.getData(ASPIRE_RESOURCE_UID) - if (resourceType != ResourceType.Project || resourceState != ResourceState.Running) { - return - } + if (resourceUid != null) { + val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) + val resourceState = event.getData(ASPIRE_RESOURCE_STATE) - AspireService.getInstance(project).scope.launch { - withBackgroundProgress(project, AspireBundle.message("progress.restart.resource")) { - SessionManager.getInstance(project).restartResource(resourceUid, false) + if (resourceType == ResourceType.Project && resourceState == ResourceState.Running) { + currentThreadCoroutineScope().launch { + withBackgroundProgress(project, AspireBundle.message("progress.stop.resource")) { + SessionManager.getInstance(project).restartResource(resourceUid, false) + } + } + } + } else { + val projectEntity = event.dataContext + .getProjectModelEntity(true) + ?.containingProjectEntity() + ?: return + val projectPath = projectEntity.url?.toPath() ?: return + val resourceId = SessionManager.getInstance(project).getResourceIdByProject(projectPath) ?: return + + currentThreadCoroutineScope().launch { + withBackgroundProgress(project, AspireBundle.message("progress.stop.resource")) { + SessionManager.getInstance(project).restartResource(resourceId, false) + } } } } @@ -40,24 +59,49 @@ class RestartResourceAction : AnAction() { } val resourceUid = event.getData(ASPIRE_RESOURCE_UID) - val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) - val resourceState = event.getData(ASPIRE_RESOURCE_STATE) - if (resourceUid == null || resourceType == null || resourceState == null) { - event.presentation.isEnabledAndVisible = false - return - } - if (resourceType != ResourceType.Project || resourceState != ResourceState.Running) { - event.presentation.isEnabledAndVisible = false - return - } + if (resourceUid != null) { + val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) + val resourceState = event.getData(ASPIRE_RESOURCE_STATE) - if (!SessionManager.getInstance(project).isResourceRunning(resourceUid)) { - event.presentation.isEnabledAndVisible = false - return - } + if (resourceType != ResourceType.Project || resourceState != ResourceState.Running) { + event.presentation.isEnabledAndVisible = false + return + } + + if (!SessionManager.getInstance(project).isResourceRunning(resourceUid)) { + event.presentation.isEnabledAndVisible = false + return + } + + event.presentation.isEnabledAndVisible = true + } else { + val projectEntity = event.dataContext.getProjectModelEntity(true)?.containingProjectEntity() + + if (projectEntity == null) { + event.presentation.isEnabledAndVisible = false + return + } - event.presentation.isEnabledAndVisible = true + val projectPath = projectEntity.url?.toPath() + if (projectPath == null) { + event.presentation.isEnabledAndVisible = false + return + } + + val resourceId = SessionManager.getInstance(project).getResourceIdByProject(projectPath) + if (resourceId == null) { + event.presentation.isEnabledAndVisible = false + return + } + + if (!SessionManager.getInstance(project).isResourceRunning(resourceId)) { + event.presentation.isEnabledAndVisible = false + return + } + + event.presentation.isEnabledAndVisible = true + } } override fun getActionUpdateThread() = ActionUpdateThread.EDT diff --git a/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/StopResourceAction.kt b/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/StopResourceAction.kt index d6ea4d73..a0069e27 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/StopResourceAction.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/actions/dashboard/StopResourceAction.kt @@ -1,12 +1,17 @@ +@file:Suppress("UnstableApiUsage") + package me.rafaelldi.aspire.actions.dashboard import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnAction import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.progress.currentThreadCoroutineScope import com.intellij.platform.ide.progress.withBackgroundProgress +import com.intellij.workspaceModel.ide.toPath +import com.jetbrains.rider.projectView.workspace.containingProjectEntity +import com.jetbrains.rider.projectView.workspace.getProjectModelEntity import kotlinx.coroutines.launch import me.rafaelldi.aspire.AspireBundle -import me.rafaelldi.aspire.AspireService import me.rafaelldi.aspire.generated.ResourceState import me.rafaelldi.aspire.generated.ResourceType import me.rafaelldi.aspire.sessionHost.SessionManager @@ -17,17 +22,31 @@ import me.rafaelldi.aspire.util.ASPIRE_RESOURCE_UID class StopResourceAction : AnAction() { override fun actionPerformed(event: AnActionEvent) { val project = event.project ?: return - val resourceUid = event.getData(ASPIRE_RESOURCE_UID) ?: return - val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) ?: return - val resourceState = event.getData(ASPIRE_RESOURCE_STATE) ?: return + val resourceUid = event.getData(ASPIRE_RESOURCE_UID) - if (resourceType != ResourceType.Project || resourceState != ResourceState.Running) { - return - } + if (resourceUid != null) { + val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) + val resourceState = event.getData(ASPIRE_RESOURCE_STATE) - AspireService.getInstance(project).scope.launch { - withBackgroundProgress(project, AspireBundle.message("progress.stop.resource")) { - SessionManager.getInstance(project).stopResource(resourceUid) + if (resourceType == ResourceType.Project && resourceState == ResourceState.Running) { + currentThreadCoroutineScope().launch { + withBackgroundProgress(project, AspireBundle.message("progress.stop.resource")) { + SessionManager.getInstance(project).stopResource(resourceUid) + } + } + } + } else { + val projectEntity = event.dataContext + .getProjectModelEntity(true) + ?.containingProjectEntity() + ?: return + val projectPath = projectEntity.url?.toPath() ?: return + val resourceId = SessionManager.getInstance(project).getResourceIdByProject(projectPath) ?: return + + currentThreadCoroutineScope().launch { + withBackgroundProgress(project, AspireBundle.message("progress.stop.resource")) { + SessionManager.getInstance(project).stopResource(resourceId) + } } } } @@ -40,24 +59,49 @@ class StopResourceAction : AnAction() { } val resourceUid = event.getData(ASPIRE_RESOURCE_UID) - val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) - val resourceState = event.getData(ASPIRE_RESOURCE_STATE) - if (resourceUid == null || resourceType == null || resourceState == null) { - event.presentation.isEnabledAndVisible = false - return - } - if (resourceType != ResourceType.Project || resourceState != ResourceState.Running) { - event.presentation.isEnabledAndVisible = false - return - } + if (resourceUid != null) { + val resourceType = event.getData(ASPIRE_RESOURCE_TYPE) + val resourceState = event.getData(ASPIRE_RESOURCE_STATE) - if (!SessionManager.getInstance(project).isResourceRunning(resourceUid)) { - event.presentation.isEnabledAndVisible = false - return - } + if (resourceType != ResourceType.Project || resourceState != ResourceState.Running) { + event.presentation.isEnabledAndVisible = false + return + } + + if (!SessionManager.getInstance(project).isResourceRunning(resourceUid)) { + event.presentation.isEnabledAndVisible = false + return + } + + event.presentation.isEnabledAndVisible = true + } else { + val projectEntity = event.dataContext.getProjectModelEntity(true)?.containingProjectEntity() + + if (projectEntity == null) { + event.presentation.isEnabledAndVisible = false + return + } - event.presentation.isEnabledAndVisible = true + val projectPath = projectEntity.url?.toPath() + if (projectPath == null) { + event.presentation.isEnabledAndVisible = false + return + } + + val resourceId = SessionManager.getInstance(project).getResourceIdByProject(projectPath) + if (resourceId == null) { + event.presentation.isEnabledAndVisible = false + return + } + + if (!SessionManager.getInstance(project).isResourceRunning(resourceId)) { + event.presentation.isEnabledAndVisible = false + return + } + + event.presentation.isEnabledAndVisible = true + } } override fun getActionUpdateThread() = ActionUpdateThread.EDT diff --git a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/SessionManager.kt b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/SessionManager.kt index 78ed55ff..99abe9a3 100644 --- a/src/main/kotlin/me/rafaelldi/aspire/sessionHost/SessionManager.kt +++ b/src/main/kotlin/me/rafaelldi/aspire/sessionHost/SessionManager.kt @@ -21,7 +21,9 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import me.rafaelldi.aspire.generated.SessionModel import me.rafaelldi.aspire.run.AspireHostConfig +import java.nio.file.Path import java.util.concurrent.ConcurrentHashMap +import kotlin.io.path.Path @Service(Service.Level.PROJECT) class SessionManager(private val project: Project, scope: CoroutineScope) { @@ -33,6 +35,7 @@ class SessionManager(private val project: Project, scope: CoroutineScope) { private val sessions = mutableMapOf() private val resourceToSessionMap = mutableMapOf() + private val projectPathToResourceIdMap = mutableMapOf>() private val sessionsUnderRestart = ConcurrentHashMap() private val commands = MutableSharedFlow( @@ -90,12 +93,14 @@ class SessionManager(private val project: Project, scope: CoroutineScope) { LOG.trace("Connection between resource $idValue and session ${command.sessionId}") resourceToSessionMap[idValue] = command.sessionId + projectPathToResourceIdMap[Path(command.sessionModel.projectPath)] = command.sessionId to idValue } private suspend fun handleDeleteCommand(command: DeleteSessionCommand) { LOG.trace("Deleting session ${command.sessionId}") resourceToSessionMap.removeIf { it.value == command.sessionId } + projectPathToResourceIdMap.removeIf { it.value.first == command.sessionId } sessionsUnderRestart.remove(command.sessionId) val session = sessions.remove(command.sessionId) ?: return @@ -110,6 +115,8 @@ class SessionManager(private val project: Project, scope: CoroutineScope) { commands.emit(command) } + fun getResourceIdByProject(projectPath: Path) = projectPathToResourceIdMap[projectPath]?.second + fun isResourceRunning(resourceId: String): Boolean { val sessionId = resourceToSessionMap[resourceId] ?: return false val session = sessions[sessionId] ?: return false @@ -151,6 +158,7 @@ class SessionManager(private val project: Project, scope: CoroutineScope) { LOG.trace("Stopping resource $resourceId") val sessionId = resourceToSessionMap.remove(resourceId) ?: return + projectPathToResourceIdMap.removeIf { it.value.second == resourceId } sessionsUnderRestart.remove(sessionId) val session = sessions.remove(sessionId) ?: return if (session.lifetimeDefinition.isNotAlive) return @@ -171,6 +179,7 @@ class SessionManager(private val project: Project, scope: CoroutineScope) { if (sessionUnderRestart != null) return resourceToSessionMap.removeIf { it.value == sessionId } + projectPathToResourceIdMap.removeIf { it.value.first == sessionId } val session = sessions.remove(sessionId) ?: return if (session.lifetimeDefinition.isNotAlive) return