Skip to content

Commit 97b5ece

Browse files
committed
fix listprofile throttle error storm, only allow 1 service call at a time
1 parent 626038d commit 97b5ece

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QLoginWebview.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ class QWebviewBrowser(val project: Project, private val parentDisposable: Dispos
325325
ApplicationManager.getApplication().executeOnPooledThread {
326326
var errorMessage = ""
327327
val profiles = try {
328-
QRegionProfileManager.getInstance().listRegionProfiles(project)
328+
QRegionProfileManager.getInstance().listProfilesCompletableFuture(project).get()
329329
} catch (e: Exception) {
330330
e.message?.let {
331331
errorMessage = it

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/profile/QRegionProfileDialog.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class QRegionProfileDialog(
7575

7676
combo.proposeModelUpdate { model ->
7777
try {
78-
QRegionProfileManager.getInstance().listRegionProfiles(project)?.forEach {
78+
QRegionProfileManager.getInstance().listProfilesCompletableFuture(project).get()?.forEach {
7979
model.addElement(it)
8080
} ?: error("Attempted to fetch profiles while there does not exist")
8181

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/profile/QRegionProfileManager.kt

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.intellij.openapi.project.Project
1515
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
1616
import com.intellij.util.xmlb.annotations.MapAnnotation
1717
import com.intellij.util.xmlb.annotations.Property
18+
import kotlinx.coroutines.CoroutineScope
1819
import software.amazon.awssdk.core.SdkClient
1920
import software.aws.toolkits.core.TokenConnectionSettings
2021
import software.aws.toolkits.core.utils.debug
@@ -36,15 +37,18 @@ import software.aws.toolkits.telemetry.MetricResult
3637
import software.aws.toolkits.telemetry.Telemetry
3738
import java.time.Duration
3839
import java.util.Collections
40+
import java.util.concurrent.CompletableFuture
41+
import java.util.concurrent.Future
3942
import kotlin.reflect.KClass
4043

4144
@Service(Service.Level.APP)
4245
@State(name = "qProfileStates", storages = [Storage("aws.xml")])
43-
class QRegionProfileManager : PersistentStateComponent<QProfileState>, Disposable {
46+
class QRegionProfileManager(private val cs: CoroutineScope) : PersistentStateComponent<QProfileState>, Disposable {
4447

4548
// Map to store connectionId to its active profile
4649
private val connectionIdToActiveProfile = Collections.synchronizedMap<String, QRegionProfile>(mutableMapOf())
4750
private val connectionIdToProfileCount = mutableMapOf<String, Int>()
51+
private var job: CompletableFuture<List<QRegionProfile>?>? = null
4852

4953
init {
5054
ApplicationManager.getApplication().messageBus.connect(this)
@@ -65,7 +69,7 @@ class QRegionProfileManager : PersistentStateComponent<QProfileState>, Disposabl
6569
val conn = getIdcConnectionOrNull(project)
6670
val selected = activeProfile(project) ?: return
6771
val profiles = tryOrNull {
68-
listRegionProfiles(project)
72+
listProfilesCompletableFuture(project).get()
6973
}
7074

7175
if (profiles == null || profiles.none { it.arn == selected.arn }) {
@@ -104,6 +108,22 @@ class QRegionProfileManager : PersistentStateComponent<QProfileState>, Disposabl
104108
}
105109
}
106110

111+
fun listProfilesCompletableFuture(project: Project): CompletableFuture<List<QRegionProfile>?> {
112+
this.job?.let { ongoingJob ->
113+
return ongoingJob
114+
}
115+
116+
val future = CompletableFuture.supplyAsync {
117+
listRegionProfiles(project)
118+
}.whenComplete { t, u ->
119+
// This runs when the future completes (success or failure)
120+
this.job = null
121+
}
122+
123+
this.job = future
124+
return future
125+
}
126+
107127
fun activeProfile(project: Project): QRegionProfile? = getIdcConnectionOrNull(project)?.let { connectionIdToActiveProfile[it.id] }
108128

109129
fun hasValidConnectionButNoActiveProfile(project: Project): Boolean = getIdcConnectionOrNull(project) != null && activeProfile(project) == null

0 commit comments

Comments
 (0)