21
21
#include < chrono>
22
22
#include < core/logging/assertions.hpp>
23
23
#include < core/logging/logger.hpp>
24
+ #include < core/random/random.hpp>
24
25
#include < core/storage/fileio/fs_utils.hpp>
25
26
#include < core/storage/fileio/general_fstream.hpp>
26
27
#include < core/storage/fileio/get_s3_endpoint.hpp>
@@ -503,13 +504,33 @@ list_objects_response list_objects_impl(const s3url& parsed_url,
503
504
504
505
} else {
505
506
auto error = outcome.GetError ();
506
- // Unlike CoreErrors, S3Error Never retries. Use Http code instead.
507
- // check aws-cpp-sdk-s3/source/S3Error.cpp
508
- if (error.GetResponseCode () ==
509
- Aws::Http::HttpResponseCode::TOO_MANY_REQUESTS) {
510
- n_retry++;
507
+ /*
508
+ * Unlike CoreErrors, S3Error Never retries on S3 errors.
509
+ * Retry can be based on HTTP code or HTTP body.
510
+ *
511
+ * 1. if SDK uses HTTP code, e.g., ShouldRetry return true on 429.
512
+ * We don't need to retry on our own since SDK already made decision to
513
+ * retry based on HTTP code.
514
+ *
515
+ * 2. if SDK doesn't use HTTP code but HTTP body, we check HTTP on our
516
+ * own if SDK doesn't think it should retry based on messages in HTTP
517
+ * body. Check https://guihao-liang.github.io/2020-04-12-aws-s3-retry/
518
+ *
519
+ * */
520
+ if (!error.ShouldRetry ()) {
521
+ // SDK didn't retry for us, check retry on our own decisions
522
+ // especially for non-standard AWS error reply
523
+ if (error.GetErrorType () == Aws::S3::S3Errors::UNKNOWN &&
524
+ error.GetResponseCode () ==
525
+ Aws::Http::HttpResponseCode::TOO_MANY_REQUESTS) {
526
+ n_retry++;
527
+ } else {
528
+ // it's standard AWS error, let's stop retry immediately
529
+ // and report accordingly to user
530
+ n_retry = 3 ;
531
+ }
511
532
512
- if (n_retry = = 3 ) {
533
+ if (n_retry > = 3 ) {
513
534
// amend the error msg on the last retry failure
514
535
std::stringstream ss;
515
536
reportS3ErrorDetailed (ss, temp_url, S3Operation::List, outcome)
@@ -524,6 +545,8 @@ list_objects_response list_objects_impl(const s3url& parsed_url,
524
545
}
525
546
526
547
} else {
548
+ // error.ShouldRetry() == true
549
+ // AWS SDK already retried 3 times
527
550
std::stringstream ss;
528
551
reportS3ErrorDetailed (ss, temp_url, S3Operation::List, outcome)
529
552
<< std::endl;
0 commit comments