@@ -31,6 +31,7 @@ import com.intellij.util.net.ssl.CertificateManager
3131import kotlinx.coroutines.CoroutineScope
3232import kotlinx.coroutines.Deferred
3333import kotlinx.coroutines.Job
34+ import kotlinx.coroutines.CancellationException
3435import kotlinx.coroutines.async
3536import kotlinx.coroutines.channels.BufferOverflow
3637import kotlinx.coroutines.delay
@@ -125,6 +126,17 @@ internal class LSPProcessListener : ProcessListener {
125126
126127 override fun processTerminated (event : ProcessEvent ) {
127128 LOG .info { " LSP process terminated with exit code ${event.exitCode} " }
129+
130+ // Check for CPU profile file after process termination
131+ val processId = ProcessHandle .current().pid()
132+ val profileDir = System .getProperty(" java.io.tmpdir" ).trimEnd(' /' )
133+ val profilePath = " $profileDir /node-profile-$processId .cpuprofile"
134+ if (Files .exists(Path .of(profilePath))) {
135+ LOG .info { " CPU profile file created: $profilePath " }
136+ } else {
137+ LOG .warn { " CPU profile file not found at: $profilePath " }
138+ }
139+
128140 try {
129141 this .outputStreamWriter.close()
130142 this .outputStream.close()
@@ -463,8 +475,17 @@ private class AmazonQServerInstance(private val project: Project, private val cs
463475 val nodePath = getNodeRuntimePath(artifact.resolve(node))
464476 val emptyFile = Files .createTempFile(" empty" , null ).toAbsolutePath().toString()
465477
478+ val processId = ProcessHandle .current().pid()
479+ val profileDir = System .getProperty(" java.io.tmpdir" ).trimEnd(' /' )
480+ val profilePath = " node-profile-$processId "
481+ LOG .info { " Node.js CPU profile will be saved to: $profileDir $profilePath " }
482+
466483 val cmd = NodeExePatcher .patch(nodePath)
467484 .withParameters(
485+ " --cpu-prof" ,
486+ " --cpu-prof-dir=$profileDir " ,
487+ " --cpu-prof-name=$profilePath " ,
488+ // "--cpu-prof-name=node-profile-$processId.cpuprofile",
468489 LspSettings .getInstance().getArtifactPath() ? : artifact.resolve(" aws-lsp-codewhisperer.js" ).toString(),
469490 " --stdio" ,
470491 " --set-credentials-encryption-key" ,
@@ -721,18 +742,28 @@ private class AmazonQServerInstance(private val project: Project, private val cs
721742 // otherwise can deadlock waiting for frozen flare process
722743 cs.launch {
723744 languageServer.apply {
724- withTimeout(2000 ) {
745+ withTimeout(5000 ) {
725746 shutdown().await()
726747 exit()
727748 }
728749 }
729750 }.asCompletableFuture()
730- .get(3000 , TimeUnit .MILLISECONDS )
751+ .get(6000 , TimeUnit .MILLISECONDS )
752+ } catch (e: CancellationException ) {
753+ // Expected during shutdown, proceed with cleanup
754+ launcherHandler.process.destroy()
755+ Thread .sleep(500 )
731756 } catch (e: Exception ) {
732757 LOG .warn(e) { " LSP shutdown failed" }
733- launcherHandler.killProcess()
758+ launcherHandler.process.destroy()
759+ Thread .sleep(500 )
760+ } finally {
761+ if (! launcherHandler.isProcessTerminated) {
762+ launcherHandler.killProcess()
763+ }
734764 }
735765 } else if (! launcherHandler.isProcessTerminated) {
766+ Thread .sleep(500 )
736767 launcherHandler.killProcess()
737768 }
738769 }
0 commit comments