Skip to content

Commit 41b6404

Browse files
authored
[JetBrains] improve handling of client connection termination (#20288)
* [JetBrains] improve handling of client connection termination * Hold connection provider until workspace stopped * use lifetime launch * delay 5 seconds
1 parent 2ffa717 commit 41b6404

File tree

1 file changed

+49
-3
lines changed

1 file changed

+49
-3
lines changed

components/ide/jetbrains/gateway-plugin/src/main/kotlin/io/gitpod/jetbrains/gateway/GitpodConnectionProvider.kt

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@ import com.jetbrains.rd.util.ConcurrentHashMap
4141
import com.jetbrains.rd.util.URI
4242
import com.jetbrains.rd.util.lifetime.Lifetime
4343
import com.jetbrains.rd.util.lifetime.LifetimeDefinition
44+
import com.jetbrains.rd.util.threading.coroutines.launch
4445
import io.gitpod.gitpodprotocol.api.entities.WorkspaceInstance
4546
import io.gitpod.jetbrains.gateway.common.GitpodConnectionHandleFactory
4647
import io.gitpod.jetbrains.icons.GitpodIcons
4748
import kotlinx.coroutines.*
4849
import kotlinx.coroutines.future.await
50+
import java.awt.Component
4951
import java.net.URL
5052
import java.net.http.HttpClient
5153
import java.net.http.HttpRequest
@@ -71,6 +73,17 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
7173
private val jacksonMapper = jacksonObjectMapper()
7274
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
7375

76+
77+
private fun showTimedOutDialogDialog(workspaceId: String, detail: String?) {
78+
val title = "Workspace Timed Out"
79+
val message = "Your workspace $workspaceId has timed out${if (detail.isNullOrBlank()) "" else " : $detail"}."
80+
val okButton = Messages.getOkButton()
81+
val options = arrayOf(okButton)
82+
val defaultIndex = 0
83+
val icon = Messages.getInformationIcon()
84+
Messages.showDialog(message, title, options, defaultIndex, icon)
85+
}
86+
7487
override suspend fun connect(
7588
parameters: Map<String, String>,
7689
requestor: ConnectionRequestor
@@ -188,6 +201,7 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
188201
var thinClientJob: Job? = null
189202

190203
var lastUpdate: WorkspaceInstance? = null
204+
var canceledByGitpod = false
191205
try {
192206
for (update in updates) {
193207
try {
@@ -255,8 +269,8 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
255269
statusMessage.text = ""
256270
}
257271
}
258-
259272
if (update.status.phase == "stopping" || update.status.phase == "stopped") {
273+
canceledByGitpod = true
260274
thinClientJob?.cancel()
261275
thinClient?.close()
262276
}
@@ -295,9 +309,41 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
295309
SshHostTunnelConnector(credentials),
296310
URI(joinLinkResp.joinLink)
297311
)
312+
var triggeredClientClosed = false
298313
clientHandle.clientClosed.advise(connectionLifetime) {
299-
application.invokeLater {
300-
connectionLifetime.terminate()
314+
// Been canceled by user
315+
if (!canceledByGitpod) {
316+
connectionLifetime.launch {
317+
// Delay for 5 seconds to see if thinClient could be terminated in time
318+
// Then we don't see error dialog from Gateway
319+
delay(5000)
320+
application.invokeLater {
321+
connectionLifetime.terminate()
322+
}
323+
}
324+
return@advise
325+
}
326+
if (triggeredClientClosed) {
327+
return@advise
328+
}
329+
triggeredClientClosed = true
330+
// Wait until workspace is stopped
331+
suspend fun waitUntilStopped(): Boolean {
332+
while (lastUpdate.status.phase != "stopped") {
333+
delay(1000)
334+
}
335+
return true
336+
}
337+
// Check if it's timed out, if so, show timed out dialog
338+
connectionLifetime.launch {
339+
val isInStoppedPhase = waitUntilStopped()
340+
val isTimedOut = isInStoppedPhase && phaseMessage.text == "Timed Out"
341+
application.invokeLater {
342+
if (isTimedOut) {
343+
showTimedOutDialogDialog(connectParams.resolvedWorkspaceId, lastUpdate.status.conditions.timeout)
344+
}
345+
connectionLifetime.terminate()
346+
}
301347
}
302348
}
303349
clientHandle.onClientPresenceChanged.advise(connectionLifetime) {

0 commit comments

Comments
 (0)