Skip to content

Commit b5aebad

Browse files
committed
delay + batch to avoid too many threads
Tool: gitpod/catfood.gitpod.cloud
1 parent 18dea22 commit b5aebad

File tree

1 file changed

+52
-18
lines changed

1 file changed

+52
-18
lines changed

components/ide/jetbrains/backend-plugin/src/main/kotlin/io/gitpod/jetbrains/remote/AbstractGitpodPortForwardingService.kt

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import java.util.*
2626
import java.util.concurrent.CompletableFuture
2727
import java.util.concurrent.ConcurrentHashMap
2828
import java.util.concurrent.atomic.AtomicReference
29+
import java.util.concurrent.Semaphore
2930

3031
@Suppress("UnstableApiUsage")
3132
abstract class AbstractGitpodPortForwardingService : GitpodPortForwardingService {
@@ -50,6 +51,13 @@ abstract class AbstractGitpodPortForwardingService : GitpodPortForwardingService
5051
// Debounce job for port updates
5152
private var debounceJob: Job? = null
5253

54+
// Batch size for port operations
55+
private val BATCH_SIZE = 10
56+
private val BATCH_DELAY = 100
57+
58+
// Semaphore to limit concurrent operations
59+
private val operationSemaphore = Semaphore(10)
60+
5361
init { start() }
5462

5563
private fun start() {
@@ -106,7 +114,7 @@ abstract class AbstractGitpodPortForwardingService : GitpodPortForwardingService
106114

107115
// Create new debounce job
108116
debounceJob = runJob(lifetime) {
109-
delay(300) // 300ms debounce delay
117+
delay(500)
110118
try {
111119
if (syncInProgress.compareAndSet(false, true)) {
112120
try {
@@ -175,30 +183,56 @@ abstract class AbstractGitpodPortForwardingService : GitpodPortForwardingService
175183
.map { it.hostPortNumber }
176184
.filter { portsNumbersFromNonServedPorts.contains(it) || !portsNumbersFromPortsList.contains(it) }
177185

178-
// Process port changes in background
186+
// Process port changes in background with batching
179187
runJob(lifetime) {
180188
try {
181-
// Stop unnecessary ports first
182-
forwardedPortsToStopForwarding.forEach { stopForwarding(it) }
183-
exposedPortsToStopExposingOnClient.forEach { stopExposingOnClient(it) }
184-
185-
// Start necessary ports
186-
servedPortsToStartForwarding.forEach {
187-
startForwarding(it)
188-
allPortsToKeep.add(it.localPort)
189+
forwardedPortsToStopForwarding.chunked(BATCH_SIZE).forEach { batch ->
190+
batch.forEach { port ->
191+
operationSemaphore.withPermit {
192+
stopForwarding(port)
193+
}
194+
}
195+
delay(100) // Add delay between batches
189196
}
190197

191-
exposedPortsToStartExposingOnClient.forEach {
192-
startExposingOnClient(it)
193-
allPortsToKeep.add(it.localPort)
198+
exposedPortsToStopExposingOnClient.chunked(BATCH_SIZE).forEach { batch ->
199+
batch.forEach { port ->
200+
operationSemaphore.withPermit {
201+
stopExposingOnClient(port)
202+
}
203+
}
204+
delay(BATCH_DELAY)
194205
}
195206

196-
// Update presentation for all ports
197-
application.invokeLater {
198-
portsList.forEach {
199-
updatePortsPresentation(it)
200-
allPortsToKeep.add(it.localPort)
207+
servedPortsToStartForwarding.chunked(BATCH_SIZE).forEach { batch ->
208+
batch.forEach { port ->
209+
operationSemaphore.withPermit {
210+
startForwarding(port)
211+
allPortsToKeep.add(port.localPort)
212+
}
213+
}
214+
delay(BATCH_DELAY)
215+
}
216+
217+
exposedPortsToStartExposingOnClient.chunked(BATCH_SIZE).forEach { batch ->
218+
batch.forEach { port ->
219+
operationSemaphore.withPermit {
220+
startExposingOnClient(port)
221+
allPortsToKeep.add(port.localPort)
222+
}
223+
}
224+
delay(BATCH_DELAY)
225+
}
226+
227+
// Update presentation for all ports in batches
228+
portsList.chunked(BATCH_SIZE).forEach { batch ->
229+
application.invokeLater {
230+
batch.forEach {
231+
updatePortsPresentation(it)
232+
allPortsToKeep.add(it.localPort)
233+
}
201234
}
235+
delay(BATCH_DELAY)
202236
}
203237

204238
cleanupUnusedLifetimes(allPortsToKeep)

0 commit comments

Comments
 (0)