-
Notifications
You must be signed in to change notification settings - Fork 945
Closed
Labels
bugThis issue is a bug.This issue is a bug.
Description
Describe the bug
FutureCancelledException is thrown when api call timed out. (Using S3AsyncClient)
Expected Behavior
It should be not throw FutureCancelledException when api call timed out.
Current Behavior
It throw FutureCancelledException, and logging messages.
An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
FutureCancelledException
software.amazon.awssdk.core.exception.ApiCallAttemptTimeoutException: HTTP request execution did not complete before the specified timeout configuration: 60000 millis
Sentry Capture
S3AsyncClient Configuration
@Configuration
@EnableConfigurationProperties(S3ClientConfig.S3ClientConfigurationProperties::class)
open class S3ClientConfig(
private val properties: S3ClientConfigurationProperties
) {
companion object {
private const val HTTP_CLIENT_MAX_CONCURRENCY = 10000
private const val MAX_PENDING_CONNECTION_ACQUIRE = 10000
private val LOG = LoggerFactory.getLogger(this::class.java)
private val CONNECTION_TIMEOUT = Duration.ofSeconds(5)
private val CONNECTION_ACQUISITION_TIMEOUT = Duration.ofSeconds(5)
private val WRITE_TIMEOUT = Duration.ofMinutes(3)
private val READ_TIMEOUT = Duration.ofMinutes(3)
}
@Bean
open fun s3AsyncClient(): S3AsyncClient {
val clientBuilder = S3AsyncClient.builder()
.httpClient(getHttpClient())
.serviceConfiguration(getServiceConfiguration())
.region(getS3Region())
.credentialsProvider(getS3CredentialProvider())
.overrideConfiguration { it
.retryPolicy(RetryPolicy.none())
.apiCallAttemptTimeout(Duration.ofMinutes(1L))
.apiCallTimeout(Duration.ofMinutes(2L))
}
.asyncConfiguration { it.advancedOption(SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR, Dispatchers.IO.asExecutor()) }
if (properties.getEndpoint() != null) {
clientBuilder.endpointOverride(properties.getEndpoint())
}
return clientBuilder.build()
}
private fun getHttpClient(): SdkAsyncHttpClient {
return NettyNioAsyncHttpClient.builder()
.protocol(Protocol.HTTP1_1)
.tcpKeepAlive(true)
.writeTimeout(WRITE_TIMEOUT)
.readTimeout(READ_TIMEOUT)
.connectionTimeout(CONNECTION_TIMEOUT)
.connectionAcquisitionTimeout(CONNECTION_ACQUISITION_TIMEOUT)
.maxConcurrency(HTTP_CLIENT_MAX_CONCURRENCY)
.maxPendingConnectionAcquires(MAX_PENDING_CONNECTION_ACQUIRE)
.build()
}
private fun getServiceConfiguration(): S3Configuration {
return S3Configuration.builder()
.checksumValidationEnabled(false)
.chunkedEncodingEnabled(true)
.accelerateModeEnabled(true)
.dualstackEnabled(true)
.build()
}
private fun getS3Region(): Region {
return Region.of(properties.getRegion())
}
private fun getS3CredentialProvider(): AwsCredentialsProvider {
try {
return DefaultCredentialsProvider.create()
} catch (ex: Exception) {
LOG.error("Invalid S3 Credential Configuration Properties")
throw InvalidAWSCredentialException("Invalid AWS Credential detected")
}
}
@ConstructorBinding
@ConfigurationProperties("test.storage.aws.s3")
@Validated
class S3ClientConfigurationProperties(
@field:NotBlank private val region: String,
private val endpoint: URI?
) {
internal fun getRegion() = region
internal fun getEndpoint() = endpoint
override fun toString(): String {
return "S3ClientConfigurationProperties(" +
"region=${getRegion()}, " +
"endpoint=${getEndpoint()}, " +
")"
}
}
}
Environment
- Spring Boot : 2.5.4
- Kotlin : 1.5.30
- org.jetbrains.kotlinx:kotlinx-coroutines-bom : 1.5.1
- org.jetbrains.kotlinx:kotlinx-coroutines-core
- org.jetbrains.kotlinx:kotlinx-coroutines-jdk8
- org.jetbrains.kotlinx:kotlinx-coroutines-reactor
- AWS Java SDK V2 version : 2.17.36
- software.amazon.awssdk:bom
- software.amazon.awssdk:s3
- software.amazon.awssdk:netty-nio-client
- software.amazon.awssdk:sts
- JDK version : java-11-amazon-corretto
- Operating System and version: Amazon Linux 2
Metadata
Metadata
Assignees
Labels
bugThis issue is a bug.This issue is a bug.