@@ -12,6 +12,7 @@ import com.intellij.ide.BrowserUtil
12
12
import com.intellij.openapi.components.service
13
13
import com.intellij.openapi.diagnostic.thisLogger
14
14
import com.intellij.openapi.progress.ProgressManager
15
+ import com.intellij.openapi.ui.Messages
15
16
import com.intellij.remote.RemoteCredentialsHolder
16
17
import com.intellij.ssh.AskAboutHostKey
17
18
import com.intellij.ssh.OpenSshLikeHostKeyVerifier
@@ -31,6 +32,7 @@ import com.jetbrains.gateway.ssh.ClientOverSshTunnelConnector
31
32
import com.jetbrains.gateway.ssh.SshHostTunnelConnector
32
33
import com.jetbrains.gateway.thinClientLink.ThinClientHandle
33
34
import com.jetbrains.rd.util.URI
35
+ import com.jetbrains.rd.util.concurrentMapOf
34
36
import com.jetbrains.rd.util.lifetime.Lifetime
35
37
import io.gitpod.gitpodprotocol.api.entities.WorkspaceInstance
36
38
import io.gitpod.jetbrains.icons.GitpodIcons
@@ -49,7 +51,7 @@ import kotlin.coroutines.coroutineContext
49
51
50
52
@Suppress(" UnstableApiUsage" , " OPT_IN_USAGE" )
51
53
class GitpodConnectionProvider : GatewayConnectionProvider {
52
-
54
+ private val activeConnections = concurrentMapOf< String , Boolean >()
53
55
private val gitpod = service<GitpodConnectionService >()
54
56
55
57
private val httpClient = HttpClient .newBuilder()
@@ -59,6 +61,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
59
61
private val jacksonMapper = jacksonObjectMapper()
60
62
.configure(DeserializationFeature .FAIL_ON_UNKNOWN_PROPERTIES , false )
61
63
64
+
62
65
override suspend fun connect (
63
66
parameters : Map <String , String >,
64
67
requestor : ConnectionRequestor
@@ -74,6 +77,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
74
77
parameters[" workspaceId" ]!! ,
75
78
parameters[" backendPort" ]
76
79
)
80
+
77
81
val client = gitpod.obtainClient(connectParams.gitpodHost)
78
82
val connectionLifetime = Lifetime .Eternal .createNested()
79
83
val updates = client.listenToWorkspace(connectionLifetime, connectParams.workspaceId)
@@ -144,6 +148,24 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
144
148
connectionPanel.repaint()
145
149
}
146
150
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
+
147
169
GlobalScope .launch {
148
170
var thinClient: ThinClientHandle ? = null
149
171
var thinClientJob: Job ? = null
@@ -230,6 +252,12 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
230
252
setErrorMessage(" failed to fetch JetBrains Gateway Join Link." )
231
253
return @launch
232
254
}
255
+
256
+ // TODO: is this the right place?
257
+ activeConnections[connectionKeyId] = true
258
+
259
+ thisLogger().warn(" Storing connection for $connectionKeyId " )
260
+
233
261
val connector = ClientOverSshTunnelConnector (
234
262
connectionLifetime,
235
263
SshHostTunnelConnector (credentials),
@@ -239,6 +267,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
239
267
clientHandle.clientClosed.advise(connectionLifetime) {
240
268
application.invokeLater {
241
269
connectionLifetime.terminate()
270
+ // todo: remove this connection from activeConnections
242
271
}
243
272
}
244
273
clientHandle.onClientPresenceChanged.advise(connectionLifetime) {
0 commit comments