@@ -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
@@ -30,8 +31,10 @@ import com.jetbrains.gateway.api.*
30
31
import com.jetbrains.gateway.ssh.ClientOverSshTunnelConnector
31
32
import com.jetbrains.gateway.ssh.SshHostTunnelConnector
32
33
import com.jetbrains.gateway.thinClientLink.ThinClientHandle
34
+ import com.jetbrains.rd.util.ConcurrentHashMap
33
35
import com.jetbrains.rd.util.URI
34
36
import com.jetbrains.rd.util.lifetime.Lifetime
37
+ import com.jetbrains.rd.util.lifetime.LifetimeDefinition
35
38
import io.gitpod.gitpodprotocol.api.entities.WorkspaceInstance
36
39
import io.gitpod.jetbrains.icons.GitpodIcons
37
40
import kotlinx.coroutines.*
@@ -49,7 +52,7 @@ import kotlin.coroutines.coroutineContext
49
52
50
53
@Suppress(" UnstableApiUsage" , " OPT_IN_USAGE" )
51
54
class GitpodConnectionProvider : GatewayConnectionProvider {
52
-
55
+ private val activeConnections = ConcurrentHashMap < String , LifetimeDefinition >()
53
56
private val gitpod = service<GitpodConnectionService >()
54
57
55
58
private val httpClient = HttpClient .newBuilder()
@@ -74,8 +77,34 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
74
77
parameters[" workspaceId" ]!! ,
75
78
parameters[" backendPort" ]
76
79
)
80
+
81
+ val connectionKeyId = " ${connectParams.gitpodHost} -${connectParams.workspaceId} -${connectParams.backendPort} "
82
+
83
+ var found = true
84
+ val connectionLifetime = activeConnections.computeIfAbsent(connectionKeyId) {
85
+ found = false
86
+ Lifetime .Eternal .createNested()
87
+ }
88
+
89
+ if (found) {
90
+ val message =
91
+ " You are trying to connect to a workspace that has a client already open. Check for opened JetBrains clients on your machine"
92
+ val title = " ${connectParams.workspaceId} (${connectParams.gitpodHost} )"
93
+ val okButton = Messages .getOkButton()
94
+ val options = arrayOf(okButton)
95
+ val defaultIndex = 0
96
+ val icon = Messages .getWarningIcon()
97
+ Messages .showDialog(message, title, options, defaultIndex, icon)
98
+
99
+ val errMessage = " A connection to the same workspace already exists: $connectionKeyId "
100
+ throw IllegalStateException (errMessage)
101
+ } else {
102
+ connectionLifetime.onTermination {
103
+ activeConnections.remove(connectionKeyId)
104
+ }
105
+ }
106
+
77
107
val client = gitpod.obtainClient(connectParams.gitpodHost)
78
- val connectionLifetime = Lifetime .Eternal .createNested()
79
108
val updates = client.listenToWorkspace(connectionLifetime, connectParams.workspaceId)
80
109
val workspace = client.syncWorkspace(connectParams.workspaceId).workspace
81
110
@@ -216,7 +245,8 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
216
245
thinClientJob = launch {
217
246
try {
218
247
val updatedIdeUrl = URL (update.ideUrl);
219
- val sshHostUrl = URL (update.ideUrl.replace(update.workspaceId, " ${update.workspaceId} .ssh" ));
248
+ val sshHostUrl =
249
+ URL (update.ideUrl.replace(update.workspaceId, " ${update.workspaceId} .ssh" ));
220
250
val hostKeys = resolveHostKeys(updatedIdeUrl, connectParams)
221
251
if (hostKeys.isNullOrEmpty()) {
222
252
setErrorMessage(" ${connectParams.gitpodHost} installation does not allow SSH access, public keys cannot be found" )
0 commit comments