@@ -12,6 +12,7 @@ import com.intellij.ide.BrowserUtil
1212import com.intellij.openapi.components.service
1313import com.intellij.openapi.diagnostic.thisLogger
1414import com.intellij.openapi.progress.ProgressManager
15+ import com.intellij.openapi.ui.Messages
1516import com.intellij.remote.RemoteCredentialsHolder
1617import com.intellij.ssh.AskAboutHostKey
1718import com.intellij.ssh.OpenSshLikeHostKeyVerifier
@@ -31,6 +32,7 @@ import com.jetbrains.gateway.ssh.ClientOverSshTunnelConnector
3132import com.jetbrains.gateway.ssh.SshHostTunnelConnector
3233import com.jetbrains.gateway.thinClientLink.ThinClientHandle
3334import com.jetbrains.rd.util.URI
35+ import com.jetbrains.rd.util.concurrentMapOf
3436import com.jetbrains.rd.util.lifetime.Lifetime
3537import io.gitpod.gitpodprotocol.api.entities.WorkspaceInstance
3638import io.gitpod.jetbrains.icons.GitpodIcons
@@ -49,7 +51,7 @@ import kotlin.coroutines.coroutineContext
4951
5052@Suppress(" UnstableApiUsage" , " OPT_IN_USAGE" )
5153class GitpodConnectionProvider : GatewayConnectionProvider {
52-
54+ private val activeConnections = concurrentMapOf< String , Boolean >()
5355 private val gitpod = service<GitpodConnectionService >()
5456
5557 private val httpClient = HttpClient .newBuilder()
@@ -59,6 +61,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
5961 private val jacksonMapper = jacksonObjectMapper()
6062 .configure(DeserializationFeature .FAIL_ON_UNKNOWN_PROPERTIES , false )
6163
64+
6265 override suspend fun connect (
6366 parameters : Map <String , String >,
6467 requestor : ConnectionRequestor
@@ -74,6 +77,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
7477 parameters[" workspaceId" ]!! ,
7578 parameters[" backendPort" ]
7679 )
80+
7781 val client = gitpod.obtainClient(connectParams.gitpodHost)
7882 val connectionLifetime = Lifetime .Eternal .createNested()
7983 val updates = client.listenToWorkspace(connectionLifetime, connectParams.workspaceId)
@@ -144,6 +148,24 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
144148 connectionPanel.repaint()
145149 }
146150
151+ val connectionKeyId = " ${connectParams.gitpodHost} -${connectParams.workspaceId} -${connectParams.backendPort} "
152+
153+ thisLogger().warn(" connectionKeyId 1 = $connectionKeyId " )
154+
155+ if (activeConnections.containsKey(connectionKeyId)) {
156+ val message = " You are trying to connect to a workspace that has a session already open"
157+ val title = " Oops"
158+ val okButton = Messages .getOkButton()
159+ val options = arrayOf(okButton)
160+ val defaultIndex = 0
161+ val icon = Messages .getWarningIcon()
162+ Messages .showDialog(message, title, options, defaultIndex, icon)
163+
164+ val errMessage = " A connection to the same workspace already exists: $connectionKeyId "
165+ thisLogger().warn(errMessage)
166+ throw IllegalArgumentException (errMessage)
167+ }
168+
147169 GlobalScope .launch {
148170 var thinClient: ThinClientHandle ? = null
149171 var thinClientJob: Job ? = null
@@ -230,6 +252,12 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
230252 setErrorMessage(" failed to fetch JetBrains Gateway Join Link." )
231253 return @launch
232254 }
255+
256+ // TODO: is this the right place?
257+ activeConnections[connectionKeyId] = true
258+
259+ thisLogger().warn(" Storing connection for $connectionKeyId " )
260+
233261 val connector = ClientOverSshTunnelConnector (
234262 connectionLifetime,
235263 SshHostTunnelConnector (credentials),
@@ -239,6 +267,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
239267 clientHandle.clientClosed.advise(connectionLifetime) {
240268 application.invokeLater {
241269 connectionLifetime.terminate()
270+ // todo: remove this connection from activeConnections
242271 }
243272 }
244273 clientHandle.onClientPresenceChanged.advise(connectionLifetime) {
0 commit comments