Skip to content

Commit daeac8a

Browse files
committed
[GW] send additional hb on gateway plugin
1 parent b1ef79e commit daeac8a

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.jetbrains.rd.util.concurrentMapOf
1111
import com.jetbrains.rd.util.lifetime.Lifetime
1212
import com.jetbrains.rd.util.lifetime.LifetimeDefinition
1313
import io.gitpod.gitpodprotocol.api.GitpodClient
14+
import io.gitpod.gitpodprotocol.api.entities.SendHeartBeatOptions
1415
import io.gitpod.gitpodprotocol.api.entities.WorkspaceInfo
1516
import io.gitpod.gitpodprotocol.api.entities.WorkspaceInstance
1617
import kotlinx.coroutines.*
@@ -115,6 +116,10 @@ class GatewayGitpodClient(
115116
return listener
116117
}
117118

119+
suspend fun sendHeartbeat(workspaceId: String) {
120+
server.sendHeartBeat(SendHeartBeatOptions(workspaceId)).await()
121+
}
122+
118123
private suspend fun removeListener(workspaceId: String, listener: Channel<WorkspaceInstance>) {
119124
mutex.withLock {
120125
val listeners = this.listeners[workspaceId]

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import io.gitpod.jetbrains.gateway.common.GitpodConnectionHandleFactory
4747
import io.gitpod.jetbrains.icons.GitpodIcons
4848
import kotlinx.coroutines.*
4949
import kotlinx.coroutines.future.await
50-
import java.awt.Component
5150
import java.net.URL
5251
import java.net.http.HttpClient
5352
import java.net.http.HttpRequest
@@ -58,6 +57,7 @@ import javax.swing.JLabel
5857
import kotlin.coroutines.coroutineContext
5958
import kotlin.io.path.absolutePathString
6059
import kotlin.io.path.writeText
60+
import kotlin.random.Random.Default.nextInt
6161

6262
@Suppress("UnstableApiUsage", "OPT_IN_USAGE")
6363
class GitpodConnectionProvider : GatewayConnectionProvider {
@@ -202,6 +202,27 @@ class GitpodConnectionProvider : GatewayConnectionProvider {
202202

203203
var lastUpdate: WorkspaceInstance? = null
204204
var canceledByGitpod = false
205+
206+
if (settings.additionalHeartbeat) {
207+
thisLogger().info("gitpod: additional heartbeat enabled for ${connectParams.resolvedWorkspaceId}")
208+
connectionLifetime.launch {
209+
while (isActive) {
210+
val delaySeconds = 30 + nextInt(5, 15)
211+
try {
212+
if (lastUpdate?.status?.phase == "running") {
213+
client.sendHeartbeat(connectParams.actualWorkspaceId)
214+
}
215+
} catch (t: Throwable) {
216+
thisLogger().error(
217+
"gitpod: failed to send additional heartbeat for ${connectParams.resolvedWorkspaceId}",
218+
t
219+
)
220+
}
221+
delay(delaySeconds * 1000L)
222+
}
223+
}
224+
}
225+
205226
try {
206227
for (update in updates) {
207228
try {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ class GitpodSettingsConfigurable : BoundConfigurable("Gitpod") {
3131
.comment("Helpful if you are behind a firewall/proxy that blocks SSH or " +
3232
"have complicated SSH setup (bastions, proxy jumps, etc.)")
3333
}
34+
row {
35+
checkBox("Additional heartbeat")
36+
.bindSelected(state::additionalHeartbeat)
37+
.comment("Additional heartbeat when connection is connected, helps to keep the workspace alive more reliably")
38+
}
3439

3540
}
3641
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ class GitpodSettingsState : PersistentStateComponent<GitpodSettingsState> {
4545
dispatcher.multicaster.didChange()
4646
}
4747

48+
var additionalHeartbeat: Boolean = false
49+
set(value) {
50+
if (value == field) {
51+
return
52+
}
53+
field = value
54+
dispatcher.multicaster.didChange()
55+
}
56+
4857
private interface Listener : EventListener {
4958
fun didChange()
5059
}

0 commit comments

Comments
 (0)