Skip to content

WIP: [JetBrains] Improve ports listener leaking #20872

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ project(":") {
if (properties("platformType") == "RD") {
print("Rider: exclude unnecessary files")
sourceSets["main"].kotlin.exclude("**/GitpodForceUpdateMavenProjectsActivity.kt")
sourceSets["main"].kotlin.exclude("**/GitpodPortForwardingServiceImpl.kt")
sourceSets["main"].kotlin.exclude("**/maven.xml")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ import io.grpc.stub.ClientCallStreamObserver
import io.grpc.stub.ClientResponseObserver
import kotlinx.coroutines.*
import kotlinx.coroutines.future.asDeferred
import kotlinx.coroutines.flow.MutableSharedFlow
import org.apache.http.client.utils.URIBuilder
import java.util.*
import java.util.concurrent.CompletableFuture
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

@Suppress("UnstableApiUsage")
abstract class AbstractGitpodPortForwardingService : GitpodPortForwardingService {
Expand All @@ -34,8 +37,26 @@ abstract class AbstractGitpodPortForwardingService : GitpodPortForwardingService
private val perClientPortForwardingManager = service<PerClientPortForwardingManager>()
private val ignoredPortsForNotificationService = service<GitpodIgnoredPortsForNotificationService>()
private val lifetime = Lifetime.Eternal.createNested()
private val portStatusFlow = MutableSharedFlow<Status.PortsStatusResponse>()

init {
// Start collecting port status updates
runJob(lifetime) {
portStatusFlow
.let { flow -> applyThrottling(flow) }
.collect { response ->
withContext(Dispatchers.IO) {
syncPortsListWithClient(response)
}
}
}

init { start() }
start()
}

protected abstract fun runJob(lifetime: Lifetime, block: suspend CoroutineScope.() -> Unit): Job;

protected abstract suspend fun <T> applyThrottling(flow: kotlinx.coroutines.flow.Flow<T>): kotlinx.coroutines.flow.Flow<T>

private fun start() {
if (application.isHeadlessEnvironment) return
Expand All @@ -47,8 +68,6 @@ abstract class AbstractGitpodPortForwardingService : GitpodPortForwardingService
observePortsListWhileProjectIsOpen()
}

protected abstract fun runJob(lifetime: Lifetime, block: suspend CoroutineScope.() -> Unit): Job;

private fun observePortsListWhileProjectIsOpen() = runJob(lifetime) {
while (isActive) {
try {
Expand Down Expand Up @@ -86,7 +105,11 @@ abstract class AbstractGitpodPortForwardingService : GitpodPortForwardingService
}

override fun onNext(response: Status.PortsStatusResponse) {
application.invokeLater { syncPortsListWithClient(response) }
application.invokeLater {
runJob(lifetime) {
portStatusFlow.emit(response)
}
}
}

override fun onCompleted() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ package io.gitpod.jetbrains.remote

import com.jetbrains.rd.util.lifetime.Lifetime
import com.jetbrains.rd.util.threading.coroutines.launch
import io.gitpod.jetbrains.remote.AbstractGitpodPortForwardingService
import kotlinx.coroutines.CoroutineScope
import fleet.util.async.throttleLatest
import kotlinx.coroutines.flow.Flow

@Suppress("UnstableApiUsage")
class GitpodPortForwardingServiceImpl : AbstractGitpodPortForwardingService() {
override fun runJob(lifetime: Lifetime, block: suspend CoroutineScope.() -> Unit) = lifetime.launch { block() }

override suspend fun <T> applyThrottling(flow: Flow<T>): Flow<T> = flow.throttleLatest(1000)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2025 Gitpod GmbH. All rights reserved.
// Licensed under the GNU Affero General Public License (AGPL).
// See License.AGPL.txt in the project root for license information.

package io.gitpod.jetbrains.remote.optional

import com.jetbrains.rd.util.lifetime.Lifetime
import com.jetbrains.rd.util.threading.coroutines.launch
import io.gitpod.jetbrains.remote.AbstractGitpodPortForwardingService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow

@Suppress("UnstableApiUsage")
class GitpodRiderPortForwardingService : AbstractGitpodPortForwardingService() {
override fun runJob(lifetime: Lifetime, block: suspend CoroutineScope.() -> Unit) = lifetime.launch { block() }

override suspend fun <T> applyThrottling(flow: Flow<T>): Flow<T> = flow
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
<!--suppress PluginXmlValidity -->
<idea-plugin>
<extensions defaultExtensionNs="com.intellij">
<applicationService serviceInterface="io.gitpod.jetbrains.remote.GitpodPortForwardingService"
serviceImplementation="io.gitpod.jetbrains.remote.GitpodPortForwardingServiceImpl"
client="controller" preload="true"/>
</extensions>
</idea-plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
description="Disable the forced update of Maven projects when IDE opens."
restartRequired="true"/>

<applicationService serviceInterface="io.gitpod.jetbrains.remote.GitpodPortForwardingService"
serviceImplementation="io.gitpod.jetbrains.remote.optional.GitpodRiderPortForwardingService"
client="controller" preload="true" />

<applicationService serviceInterface="io.gitpod.jetbrains.remote.GitpodIgnoredPortsForNotificationService"
serviceImplementation="io.gitpod.jetbrains.remote.internal.GitpodIgnoredPortsForNotificationServiceImpl"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
<!--suppress PluginXmlValidity -->
<idea-plugin>
<extensions defaultExtensionNs="com.intellij">
<applicationService serviceInterface="io.gitpod.jetbrains.remote.GitpodPortForwardingService"
serviceImplementation="io.gitpod.jetbrains.remote.GitpodPortForwardingServiceImpl"
client="controller" preload="true"/>
</extensions>
</idea-plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@
preload="true"/>


<applicationService serviceInterface="io.gitpod.jetbrains.remote.GitpodPortForwardingService"
serviceImplementation="io.gitpod.jetbrains.remote.GitpodPortForwardingServiceImpl"
client="controller" preload="true"/>
<gateway.customization.performance id="gitpodMetricsControl" order="before cpuControl"
implementation="io.gitpod.jetbrains.remote.GitpodMetricControlProvider"/>
</extensions>
Expand Down
Loading