Skip to content

Tuning AWS Rust SDK HTTP request settings for latency-aware Amazon DynamoDB applications #558

@ymwjbxxq

Description

@ymwjbxxq

Describe the bug

As per discussion:
#557

The DynamoDB SDK does not retry based on the with_max_attempts, but its exits at the first failure.

The workaround is to put the queries inside a custom code:

let mut retry_count = 1;
while retry_count < 5 {
     let result = RunQuery().await;
     if let Ok(output) = result {
                //do something or break
      } else {
          retry_count += 1;
      }
}

Expected Behavior

If I set a timeout at 30ms and 5 retries, for example

I expect the Lambda Duration to be between > 30ms and 150ms based on retries and not exiting immediately.

Current Behavior

The SDK does not retry at all. I think it is for all the clients and not just DynamoDB

Reproduction Steps

set the following configuration:

let timeout_config = timeout::Config::new()
        .with_api_timeouts(
            timeout::Api::new()
                // This timeout acts at the "Request to a service" level. When the SDK makes a request to a
                // service, that "request" can contain several HTTP requests. This way, you can retry
                // failures that are likely spurious, or refresh credentials.
                .with_call_timeout(TriState::Set(Duration::from_millis(30)))
                // This timeout acts at the "HTTP request" level and sets a separate timeout for each
                // HTTP request made as part of a "service request."
                .with_call_attempt_timeout(TriState::Set(Duration::from_millis(30))),
        )
        .with_http_timeouts(
            timeout::Http::new()
                // A limit on the amount of time an application takes to attempt to read the first byte over
                // an established, open connection after a write request.
                // Also known as the "time to first byte" timeout.
                .with_read_timeout(TriState::Set(Duration::from_millis(10)))
                // A time limit for completing the connect-handshake. The time starts when
                // making an initial connect attempt on a socket.
                .with_connect_timeout(TriState::Set(Duration::from_millis(10))),
        );
    let config = aws_config::from_env()
        .retry_config(RetryConfig::new().with_max_attempts(10))
        .timeout_config(timeout_config)
        .load()
        .await;

    let dynamodb_client = aws_sdk_dynamodb::Client::new(&config);

you will get this message:
request has timed out: API call (single attempt) timeout occurred after 30ms.

But you will notice that the Lambda Duration is 32ms, so the SDK did not retry.

Possible Solution

Implement retries with exponential backoff like the other AWS-SDK

Additional Information/Context

Libs:

aws-sdk-dynamodb = "0.13.0"
lambda_http = "0.5.0"
lambda_runtime = "0.5.1"
rustc 1.61.0 

Version

cargo tree | grep aws- ├── aws-config v0.13.0 │   ├── aws-http v0.13.0 │   │   ├── aws-smithy-http v0.43.0 │   │   │   ├── aws-smithy-types v0.43.0 │   │   ├── aws-smithy-types v0.43.0 (*) │   │   ├── aws-types v0.13.0 │   │   │   ├── aws-smithy-async v0.43.0 │   │   │   ├── aws-smithy-client v0.43.0 │   │   │   │   ├── aws-smithy-async v0.43.0 (*) │   │   │   │   ├── aws-smithy-http v0.43.0 (*) │   │   │   │   ├── aws-smithy-http-tower v0.43.0 │   │   │   │   │   ├── aws-smithy-http v0.43.0 (*) │   │   │   │   ├── aws-smithy-protocol-test v0.43.0 │   │   │   │   ├── aws-smithy-types v0.43.0 (*) │   │   │   ├── aws-smithy-http v0.43.0 (*) │   │   │   ├── aws-smithy-types v0.43.0 (*) │   ├── aws-sdk-sso v0.13.0 │   │   ├── aws-endpoint v0.13.0 │   │   │   ├── aws-smithy-http v0.43.0 (*) │   │   │   ├── aws-types v0.13.0 (*) │   │   ├── aws-http v0.13.0 (*) │   │   ├── aws-sig-auth v0.13.0 │   │   │   ├── aws-sigv4 v0.13.0 │   │   │   │   ├── aws-smithy-http v0.43.0 (*) │   │   │   ├── aws-smithy-http v0.43.0 (*) │   │   │   ├── aws-types v0.13.0 (*) │   │   ├── aws-smithy-async v0.43.0 (*) │   │   ├── aws-smithy-client v0.43.0 (*) │   │   ├── aws-smithy-http v0.43.0 (*) │   │   ├── aws-smithy-http-tower v0.43.0 (*) │   │   ├── aws-smithy-json v0.43.0 │   │   │   └── aws-smithy-types v0.43.0 (*) │   │   ├── aws-smithy-types v0.43.0 (*) │   │   ├── aws-types v0.13.0 (*) │   ├── aws-sdk-sts v0.13.0 │   │   ├── aws-endpoint v0.13.0 (*) │   │   ├── aws-http v0.13.0 (*) │   │   ├── aws-sig-auth v0.13.0 (*) │   │   ├── aws-smithy-async v0.43.0 (*) │   │   ├── aws-smithy-client v0.43.0 (*) │   │   ├── aws-smithy-http v0.43.0 (*) │   │   ├── aws-smithy-http-tower v0.43.0 (*) │   │   ├── aws-smithy-query v0.43.0 │   │   │   ├── aws-smithy-types v0.43.0 (*) │   │   ├── aws-smithy-types v0.43.0 (*) │   │   ├── aws-smithy-xml v0.43.0 │   │   ├── aws-types v0.13.0 (*) │   ├── aws-smithy-async v0.43.0 (*) │   ├── aws-smithy-client v0.43.0 (*) │   ├── aws-smithy-http v0.43.0 (*) │   ├── aws-smithy-http-tower v0.43.0 (*) │   ├── aws-smithy-json v0.43.0 (*) │   ├── aws-smithy-types v0.43.0 (*) │   ├── aws-types v0.13.0 (*) ├── aws-sdk-cloudfront v0.13.0 │   ├── aws-endpoint v0.13.0 (*) │   ├── aws-http v0.13.0 (*) │   ├── aws-sig-auth v0.13.0 (*) │   ├── aws-smithy-async v0.43.0 (*) │   ├── aws-smithy-client v0.43.0 (*) │   ├── aws-smithy-http v0.43.0 (*) │   ├── aws-smithy-http-tower v0.43.0 (*) │   ├── aws-smithy-types v0.43.0 (*) │   ├── aws-smithy-xml v0.43.0 (*) │   ├── aws-types v0.13.0 (*) ├── aws-sdk-dynamodb v0.13.0 │   ├── aws-endpoint v0.13.0 (*) │   ├── aws-http v0.13.0 (*) │   ├── aws-sig-auth v0.13.0 (*) │   ├── aws-smithy-async v0.43.0 (*) │   ├── aws-smithy-client v0.43.0 (*) │   ├── aws-smithy-http v0.43.0 (*) │   ├── aws-smithy-http-tower v0.43.0 (*) │   ├── aws-smithy-json v0.43.0 (*) │   ├── aws-smithy-types v0.43.0 (*) │   ├── aws-types v0.13.0 (*) ├── aws-sdk-sqs v0.13.0 │   ├── aws-endpoint v0.13.0 (*) │   ├── aws-http v0.13.0 (*) │   ├── aws-sig-auth v0.13.0 (*) │   ├── aws-smithy-async v0.43.0 (*) │   ├── aws-smithy-client v0.43.0 (*) │   ├── aws-smithy-http v0.43.0 (*) │   ├── aws-smithy-http-tower v0.43.0 (*) │   ├── aws-smithy-query v0.43.0 (*) │   ├── aws-smithy-types v0.43.0 (*) │   ├── aws-smithy-xml v0.43.0 (*) │   ├── aws-types v0.13.0 (*) ├── aws-smithy-http v0.43.0 (*) ├── aws-smithy-types v0.43.0 (*) ├── aws-types v0.13.0 (*) ├── aws-smithy-client v0.43.0 (*)

Environment details (OS name and version, etc.)

Mac

Logs

ERROR lambda_runtime: SdkError("request has timed out: API call (single attempt) timeout occurred after 30ms")

Metadata

Metadata

Assignees

Labels

bugThis issue is a bug.

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions