diff --git a/CHANGELOG.md b/CHANGELOG.md index 17949f2f..fd3a2a37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Changed - renamed the plugin from `Coder Gateway` to `Gateway` +- workspaces and agents are now resolved and displayed progressively ### Fixed - icon rendering on macOS diff --git a/src/main/kotlin/com/coder/gateway/models/WorkspaceAgentModel.kt b/src/main/kotlin/com/coder/gateway/models/WorkspaceAgentModel.kt index 91367a6c..80b65e57 100644 --- a/src/main/kotlin/com/coder/gateway/models/WorkspaceAgentModel.kt +++ b/src/main/kotlin/com/coder/gateway/models/WorkspaceAgentModel.kt @@ -19,4 +19,28 @@ data class WorkspaceAgentModel( val agentOS: OS?, val agentArch: Arch?, val homeDirectory: String? -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as WorkspaceAgentModel + + if (workspaceID != other.workspaceID) return false + if (workspaceName != other.workspaceName) return false + if (name != other.name) return false + if (templateID != other.templateID) return false + if (templateName != other.templateName) return false + + return true + } + + override fun hashCode(): Int { + var result = workspaceID.hashCode() + result = 31 * result + workspaceName.hashCode() + result = 31 * result + name.hashCode() + result = 31 * result + templateID.hashCode() + result = 31 * result + templateName.hashCode() + return result + } +} diff --git a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt index 9dd29e0a..66f3753d 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt @@ -64,6 +64,7 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import org.zeroturnaround.exec.ProcessExecutor import java.awt.Component @@ -399,12 +400,20 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : val authTask = object : Task.Modal(null, CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.cli.downloader.dialog.title"), false) { override fun run(pi: ProgressIndicator) { - pi.apply { isIndeterminate = false - text = "Downloading coder cli..." + text = "Retrieving Workspaces..." fraction = 0.1 } + runBlocking { + loadWorkspaces() + } + + pi.apply { + isIndeterminate = false + text = "Downloading Coder CLI..." + fraction = 0.3 + } cliManager.downloadCLI() if (getOS() != OS.WINDOWS) { @@ -413,7 +422,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : logger.info("chmod +x ${cliManager.localCli.toAbsolutePath()} $chmodOutput") } pi.apply { - text = "Configuring coder cli..." + text = "Configuring Coder CLI..." fraction = 0.5 } @@ -424,7 +433,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : logger.info("Result of `${localWizardModel.localCliPath} config-ssh --yes --use-previous-options`: $sshConfigOutput") pi.apply { - text = "Remove old coder cli versions..." + text = "Remove old Coder CLI versions..." fraction = 0.9 } cliManager.removeOldCli() @@ -467,35 +476,50 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : poller = cs.launch { while (isActive) { - loadWorkspaces() delay(5000) + loadWorkspaces() } } } private suspend fun loadWorkspaces() { - val workspaceList = withContext(Dispatchers.IO) { + withContext(Dispatchers.IO) { + val timeBeforeRequestingWorkspaces = System.currentTimeMillis() try { - return@withContext coderClient.workspaces().collectAgents() + val ws = coderClient.workspaces() + val timeAfterRequestingWorkspaces = System.currentTimeMillis() + logger.info("Retrieving the workspaces took: ${timeAfterRequestingWorkspaces - timeBeforeRequestingWorkspaces} millis") + ws.resolveAndDisplayAgents() } catch (e: Exception) { logger.error("Could not retrieve workspaces for ${coderClient.me.username} on ${coderClient.coderURL}. Reason: $e") - emptyList() } } + } - withContext(Dispatchers.Main) { - val selectedWorkspace = tableOfWorkspaces.selectedObject?.name - listTableModelOfWorkspaces.items = workspaceList - if (selectedWorkspace != null) { - tableOfWorkspaces.selectItem(selectedWorkspace) + private fun List.resolveAndDisplayAgents() { + this.forEach { workspace -> + cs.launch(Dispatchers.IO) { + val timeBeforeRequestingAgents = System.currentTimeMillis() + workspace.agentModels().forEach { am -> + withContext(Dispatchers.Main) { + val selectedWorkspace = tableOfWorkspaces.selectedObject?.name + if (listTableModelOfWorkspaces.indexOf(am) >= 0) { + val index = listTableModelOfWorkspaces.indexOf(am) + listTableModelOfWorkspaces.setItem(index, am) + } else { + listTableModelOfWorkspaces.addRow(am) + } + if (selectedWorkspace != null) { + tableOfWorkspaces.selectItem(selectedWorkspace) + } + } + } + val timeAfterRequestingAgents = System.currentTimeMillis() + logger.info("Retrieving the agents for ${workspace.name} took: ${timeAfterRequestingAgents - timeBeforeRequestingAgents} millis") } } } - private fun List.collectAgents(): List { - return this.flatMap { it.agentModels() }.toList() - } - private fun Workspace.agentModels(): List { return try { val agents = coderClient.workspaceAgentsByTemplate(this)