diff --git a/CHANGELOG.md b/CHANGELOG.md index c473153d..51c9f576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - the proxy command now always logs in verbose mode when the log directory is enabled +### Fixed + +- no longer spam Toolbox with requests to establish the SSH connections every 5 seconds + ## 0.8.1 - 2025-12-11 ### Changed diff --git a/gradle.properties b/gradle.properties index d9ce8bf0..041b11cf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -version=0.8.1 +version=0.8.2 group=com.coder.toolbox name=coder-toolbox \ No newline at end of file diff --git a/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt b/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt index 5cf160d0..d341fa12 100644 --- a/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt +++ b/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt @@ -73,7 +73,7 @@ class CoderRemoteEnvironment( init { if (context.settingsStore.shouldAutoConnect(id)) { - context.logger.info("resuming SSH connection to $id — last session was still active.") + context.logger.info("Last session to $id was still active, trying to establish SSH connection") startSshConnection() } refreshAvailableActions() @@ -304,18 +304,15 @@ class CoderRemoteEnvironment( } /** - * Launches the SSH connection if the workspace is ready and there is no connection already established. - * - * Returns true if the SSH connection was scheduled to start, false otherwise. + * Schedules the SSH connection to start as soon as possible if the workspace is ready and there is no connection already established. */ - fun startSshConnection(): Boolean { + fun startSshConnection() { if (environmentStatus.ready() && !isConnected.value) { connectionRequest.update { true } - return true + context.logger.info("Workspace status is ready and there is no existing connection, resuming SSH connection to $id") } - return false } override val deleteActionFlow: StateFlow<(() -> Unit)?> = MutableStateFlow(null) diff --git a/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt b/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt index 98cc1ab3..9e025633 100644 --- a/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt +++ b/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt @@ -131,15 +131,14 @@ class CoderRemoteProvider( // different information? it.name }?.map { agent -> - // If we have an environment already, update that. - val env = CoderRemoteEnvironment(context, client, cli, ws, agent) - lastEnvironments.firstOrNull { it == env }?.let { - it.update(ws, agent) - it - } ?: env + lastEnvironments.firstOrNull { it.id == "${ws.name}.${agent.name}" } + ?.also { + // If we have an environment already, update that. + it.update(ws, agent) + } ?: CoderRemoteEnvironment(context, client, cli, ws, agent) } ?: emptyList() } - }.toSet() + }.toSet().sortedBy { it.id } // In case we logged out while running the query. if (!isActive) { @@ -153,7 +152,7 @@ class CoderRemoteProvider( } environments.update { - LoadableState.Value(resolvedEnvironments.toList()) + LoadableState.Value(resolvedEnvironments) } if (!isInitialized.value) { context.logger.info("Environments for ${client.url} are now initialized") @@ -163,23 +162,8 @@ class CoderRemoteProvider( } lastEnvironments.apply { clear() - addAll(resolvedEnvironments.sortedBy { it.id }) + addAll(resolvedEnvironments) } - - if (WorkspaceConnectionManager.shouldEstablishWorkspaceConnections) { - WorkspaceConnectionManager.allConnected().forEach { wsId -> - val env = lastEnvironments.firstOrNull() { it.id == wsId } - if (env != null && !env.isConnected()) { - context.logger.info("Establishing lost SSH connection for workspace with id $wsId") - if (!env.startSshConnection()) { - context.logger.info("Can't establish lost SSH connection for workspace with id $wsId") - } - } - } - WorkspaceConnectionManager.reset() - } - - WorkspaceConnectionManager.collectStatuses(lastEnvironments) } catch (_: CancellationException) { context.logger.debug("${client.url} polling loop canceled") break @@ -190,7 +174,6 @@ class CoderRemoteProvider( } else { context.logger.error(ex, "workspace polling error encountered") if (ex is APIResponseException && ex.isTokenExpired) { - WorkspaceConnectionManager.shouldEstablishWorkspaceConnections = true close() context.envPageManager.showPluginEnvironmentsPage() errorBuffer.add(ex) @@ -225,7 +208,6 @@ class CoderRemoteProvider( */ private fun logout() { context.logger.info("Logging out ${client?.me?.username}...") - WorkspaceConnectionManager.reset() close() context.logger.info("User ${client?.me?.username} logged out successfully") } diff --git a/src/main/kotlin/com/coder/toolbox/WorkspaceConnectionManager.kt b/src/main/kotlin/com/coder/toolbox/WorkspaceConnectionManager.kt deleted file mode 100644 index 91967291..00000000 --- a/src/main/kotlin/com/coder/toolbox/WorkspaceConnectionManager.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.coder.toolbox - -object WorkspaceConnectionManager { - private val workspaceConnectionState = mutableMapOf() - - var shouldEstablishWorkspaceConnections = false - - fun allConnected(): Set = workspaceConnectionState.filter { it.value }.map { it.key }.toSet() - - fun collectStatuses(workspaces: Set) { - workspaces.forEach { register(it.id, it.isConnected()) } - } - - private fun register(wsId: String, isConnected: Boolean) { - workspaceConnectionState[wsId] = isConnected - } - - fun reset() { - workspaceConnectionState.clear() - shouldEstablishWorkspaceConnections = false - } -} \ No newline at end of file