Skip to content
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

Significantly speed up loading the list of S3 buckets #2186

Merged
merged 2 commits into from Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,4 @@
{
"type" : "bugfix",
"description" : "Significantly speed up loading the list of S3 buckets (#2174)"
}
Expand Up @@ -3,6 +3,10 @@
package software.aws.toolkits.jetbrains.services.s3.resources

import com.intellij.openapi.project.Project
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.slf4j.event.Level
import software.amazon.awssdk.services.s3.S3Client
import software.amazon.awssdk.services.s3.model.Bucket
Expand All @@ -16,6 +20,7 @@ import software.aws.toolkits.jetbrains.core.credentials.AwsConnectionManager
import software.aws.toolkits.jetbrains.core.filter
import software.aws.toolkits.jetbrains.core.map
import software.aws.toolkits.jetbrains.core.region.AwsRegionProvider
import software.aws.toolkits.jetbrains.utils.ApplicationThreadPoolScope
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
Expand All @@ -26,21 +31,26 @@ object S3Resources {
private val regions by lazy { AwsRegionProvider.getInstance().allRegions() }

val LIST_REGIONALIZED_BUCKETS = ClientBackedCachedResource(S3Client::class, "s3.list_buckets") {
listBuckets().buckets().mapNotNull { bucket ->
LOG.tryOrNull("Cannot determine region for ${bucket.name()}", level = Level.WARN) {
regionForBucket(bucket.name())
}?.let { regions[it] }?.let {
RegionalizedBucket(bucket, it)
val buckets = listBuckets().buckets()
// TODO when the resource cache is coroutine based, remove the runBlocking and withContext
runBlocking {
// withContext is needed to put this on a thread pool
withContext(ApplicationThreadPoolScope("ListRegionalizedBuckets").coroutineContext) {
buckets.map { bucket ->
async {
LOG.tryOrNull("Cannot determine region for ${bucket.name()}", level = Level.WARN) {
regionForBucket(bucket.name())
}?.let { regions[it] }?.let {
RegionalizedBucket(bucket, it)
}
}
}.awaitAll().filterNotNull()
}
}
}

val LIST_BUCKETS: Resource<List<Bucket>> = LIST_REGIONALIZED_BUCKETS.map { it.bucket }

fun bucketRegion(bucketName: String): Resource<AwsRegion?> = Resource.View(LIST_REGIONALIZED_BUCKETS) {
Copy link
Contributor

@kiiadi kiiadi Nov 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was this not used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep it was unused (we use regionForBucket)

find { it.bucket.name() == bucketName }?.region
}

fun listBucketsByActiveRegion(project: Project): Resource<List<Bucket>> {
val activeRegion = AwsConnectionManager.getInstance(project).activeRegion
return LIST_REGIONALIZED_BUCKETS.filter { it.region == activeRegion }.map { it.bucket }
Expand Down