Description
Type of request: This is a ...
[x] bug report
[ ] feature request
Detailed description
Using the AWS Java SDK v2, when getting a S3 object after an SQS operation (eg: purgeQueue), the s3 operation take at least 30 seconds when using the async method, but it takes less than a second when using the sync method.
If the SQS operation is removed, both s3 operation take approximately the same time.
We also used Wireshark to inspect the HTTP requests and we saw that the main difference between the async and sync requests is "Connection: Keep-Alive" header parameter exists for the sync method, but not for the async method.
Expected behavior
We expect that both methods, async and sync, should take approximately the same time.
Actual behavior
The sync method is really fast while the async method take at least 30 seconds.
Steps to reproduce
Assuming that:
- a SQS queue with name "queueName" exists
- a S3 bucket with name "bucketName" exists
- a non-empty S3 object with name "filePath" exists
Execute the provided snippet on a Kotlin IDE and validate the different run times between the async and sync methods.
Command used to start LocalStack
Via docker container:
localstack:
image: localstack/localstack:0.11.6
container_name: localstack
ports:
- 4566:4566
- 8080:8080
environment:
- SERVICES=s3,sns,sqs
- DEFAULT_REGION=eu-west-1
- DATA_DIR=/tmp/localstack/data
- DEBUG=1
volumes:
- '~/.localstack:/tmp/localstack'
- '/var/run/docker.sock:/var/run/docker.sock'
Client code (AWS SDK code snippet, or sequence of "awslocal" commands)
fun test() = runBlocking {
val sqsClient = SqsAsyncClient.builder()
.endpointOverride(URI("http://localhost:4566"))
.build()
val sqsResponse = sqsClient.purgeQueue(
PurgeQueueRequest.builder().queueUrl("http://localhost:4566/000000000000/queueName").build()
).await()
downloadSync()
downloadAsync()
}
private suspend fun downloadAsync() {
val s3Client = S3AsyncClient.builder()
.endpointOverride(URI("http://localhost:4566"))
.build()
var startTime = Instant.now()
val fileContent = s3Client.getObject(
GetObjectRequest.builder().bucket("bucketName").key("filePath").build(),
AsyncResponseTransformer.toBytes()
).await().asString(Charset.defaultCharset())
val endTime = Instant.now()
println("Async download took: ${Duration.between(startTime, endTime)}")
}
private fun downloadSync() {
val s3Client = S3Client.builder()
.endpointOverride(URI("http://localhost:4566"))
.build()
var startTime = Instant.now()
val fileContent = s3Client.getObject(
GetObjectRequest.builder().bucket("bucketName").key("filePath").build()
).readAllBytes()!!.contentToString()
val endTime = Instant.now()
println("Sync download took: ${Duration.between(startTime, endTime)}")
}