@@ -87,7 +87,6 @@ import java.net.URI
8787import java.nio.charset.StandardCharsets
8888import java.nio.file.Files
8989import java.util.concurrent.Future
90- import kotlin.time.Duration.Companion.milliseconds
9190import kotlin.time.Duration.Companion.seconds
9291
9392// https://github.com/redhat-developer/lsp4ij/blob/main/src/main/java/com/redhat/devtools/lsp4ij/server/LSPProcessListener.java
@@ -180,31 +179,41 @@ class AmazonQLspService(private val project: Project, private val cs: CoroutineS
180179 heartbeatJob = cs.launch {
181180 while (isActive) {
182181 delay(5 .seconds) // Check every 5 seconds
183- checkConnectionStatus()
182+ val shouldLoop = checkConnectionStatus()
183+ if (! shouldLoop) {
184+ break
185+ }
184186 }
185187 }
186188 }
187189
188- private suspend fun checkConnectionStatus () {
190+ private suspend fun checkConnectionStatus (): Boolean {
189191 try {
190192 val currentInstance = mutex.withLock { instance }.await()
191193
192194 // Check if the launcher's Future (startListening) is done
193195 // If it's done, that means the connection has been terminated
194- if (currentInstance.launcherFuture.isDone) {
196+ if (currentInstance.launcherFuture.isDone || true ) {
195197 LOG .debug { " LSP server connection terminated, checking restart limits" }
196- waitForRestartSlot()
198+ val canRestart = checkForRemainingRestartAttempts()
199+ if (! canRestart) {
200+ return false
201+ }
197202 LOG .debug { " Restarting LSP server" }
198203 restart()
199204 } else {
200205 LOG .debug { " LSP server is currently running" }
201206 }
202207 } catch (e: Exception ) {
203208 LOG .debug(e) { " Connection status check failed, checking restart limits" }
204- waitForRestartSlot()
209+ val canRestart = checkForRemainingRestartAttempts()
210+ if (! canRestart) {
211+ return false
212+ }
205213 LOG .debug { " Restarting LSP server" }
206214 restart()
207215 }
216+ return true
208217 }
209218
210219 override fun dispose () {
@@ -235,7 +244,7 @@ class AmazonQLspService(private val project: Project, private val cs: CoroutineS
235244 instance = start()
236245 }
237246
238- private suspend fun waitForRestartSlot (): Unit = restartMutex.withLock {
247+ private suspend fun checkForRemainingRestartAttempts (): Boolean = restartMutex.withLock {
239248 val currentTime = System .currentTimeMillis()
240249
241250 while (restartTimestamps.isNotEmpty() &&
@@ -246,21 +255,12 @@ class AmazonQLspService(private val project: Project, private val cs: CoroutineS
246255
247256 if (restartTimestamps.size < MAX_RESTARTS ) {
248257 restartTimestamps.addLast(currentTime)
249- return
258+ return true
250259 }
251260
252- val oldestTimestamp = restartTimestamps.first()
253- val waitTimeMs = (oldestTimestamp + RESTART_WINDOW_MS ) - currentTime
254-
255- LOG .info { " Rate limit reached for LSP server restarts. Waiting ${waitTimeMs} ms for next available slot." }
256-
257- restartMutex.unlock()
258- delay(waitTimeMs.milliseconds)
261+ LOG .info { " Rate limit reached for LSP server restarts. Stop attempting to restart." }
259262
260- // After waiting, recursively call this function to check again
261- // (in case conditions changed while we were waiting)
262- waitForRestartSlot()
263- restartMutex.lock()
263+ return false
264264 }
265265
266266 suspend fun <T > execute (runnable : suspend AmazonQLspService .(AmazonQLanguageServer ) -> T ): T {
@@ -311,8 +311,7 @@ private class AmazonQServerInstance(private val project: Project, private val cs
311311 get() = launcher.remoteEndpoint
312312
313313 @Suppress(" ForbiddenVoid" )
314- var launcherFuture: Future <Void >
315- private set
314+ val launcherFuture: Future <Void >
316315 private val launcherHandler: KillableProcessHandler
317316 val initializeResult: Deferred <InitializeResult >
318317
0 commit comments