From 524737a579d4dccfa205d87ba99d9db1326acbab Mon Sep 17 00:00:00 2001 From: Ernest Zaslavsky Date: Tue, 21 Oct 2025 17:48:05 +0300 Subject: [PATCH] retry_strategy: introduce Seastar-based retry strategy Add a new class derived from Seastar's `default_retry_strategy`. Relocate the `should_retry` implementation from Scylla's `default_retry_strategy` into the new class to centralize and standardize retry behavior. --- utils/s3/default_aws_retry_strategy.cc | 30 ++++++++++++-------------- utils/s3/default_aws_retry_strategy.hh | 26 ++++------------------ 2 files changed, 18 insertions(+), 38 deletions(-) diff --git a/utils/s3/default_aws_retry_strategy.cc b/utils/s3/default_aws_retry_strategy.cc index 5d459f1258..5235795f1e 100644 --- a/utils/s3/default_aws_retry_strategy.cc +++ b/utils/s3/default_aws_retry_strategy.cc @@ -8,40 +8,38 @@ #include "default_aws_retry_strategy.hh" #include "aws_error.hh" +#include "seastar/http/exception.hh" +#include "seastar/util/short_streams.hh" #include "utils/log.hh" +namespace seastar::http::experimental { +extern logging::logger rs_logger; +} + using namespace std::chrono_literals; +using namespace seastar::http::experimental; namespace aws { -static logging::logger rs_logger("default_retry_strategy"); - -default_aws_retry_strategy::default_aws_retry_strategy(unsigned max_retries, unsigned scale_factor) : _max_retries(max_retries), _scale_factor(scale_factor) { +default_aws_retry_strategy::default_aws_retry_strategy(unsigned max_retries) : _max_retries(max_retries) { } -seastar::future default_aws_retry_strategy::should_retry(const aws_error& error, unsigned attempted_retries) const { +seastar::future default_aws_retry_strategy::should_retry(std::exception_ptr error, unsigned attempted_retries) const { if (attempted_retries >= _max_retries) { rs_logger.warn("Retries exhausted. Retry# {}", attempted_retries); co_return false; } - bool should_retry = error.is_retryable() == retryable::yes; + auto err = aws_error::from_exception_ptr(error); + bool should_retry = err.is_retryable() == retryable::yes; if (should_retry) { - rs_logger.debug("AWS HTTP client request failed. Reason: {}. Retry# {}", error.get_error_message(), attempted_retries); + rs_logger.debug("AWS HTTP client request failed. Reason: {}. Retry# {}", err.get_error_message(), attempted_retries); } else { rs_logger.warn("AWS HTTP client encountered non-retryable error. Reason: {}. Code: {}. Retry# {}", - error.get_error_message(), - std::to_underlying(error.get_error_type()), + err.get_error_message(), + std::to_underlying(err.get_error_type()), attempted_retries); } co_return should_retry; } -std::chrono::milliseconds default_aws_retry_strategy::delay_before_retry(const aws_error&, unsigned attempted_retries) const { - if (attempted_retries == 0) { - return 0ms; - } - - return std::chrono::milliseconds((1UL << attempted_retries) * _scale_factor); -} - } // namespace aws diff --git a/utils/s3/default_aws_retry_strategy.hh b/utils/s3/default_aws_retry_strategy.hh index d6dee8279c..deeab7c21f 100644 --- a/utils/s3/default_aws_retry_strategy.hh +++ b/utils/s3/default_aws_retry_strategy.hh @@ -7,38 +7,20 @@ */ #pragma once -#include -#include +#include namespace aws { class aws_error; -class retry_strategy { -public: - virtual ~retry_strategy() = default; - // Returns true if the error can be retried given the error and the number of times already tried. - virtual seastar::future should_retry(const aws_error& error, unsigned attempted_retries) const = 0; - - // Calculates the time in milliseconds the client should wait before attempting another request based on the error and attemptedRetries count. - [[nodiscard]] virtual std::chrono::milliseconds delay_before_retry(const aws_error& error, unsigned attempted_retries) const = 0; - - [[nodiscard]] virtual unsigned get_max_retries() const = 0; -}; - -class default_aws_retry_strategy : public retry_strategy { +class default_aws_retry_strategy : public seastar::http::experimental::retry_strategy { protected: unsigned _max_retries; - unsigned _scale_factor; public: - explicit default_aws_retry_strategy(unsigned max_retries = 10, unsigned scale_factor = 25); + explicit default_aws_retry_strategy(unsigned max_retries = 10); - seastar::future should_retry(const aws_error& error, unsigned attempted_retries) const override; - - [[nodiscard]] std::chrono::milliseconds delay_before_retry(const aws_error& error, unsigned attempted_retries) const override; - - [[nodiscard]] unsigned get_max_retries() const override { return _max_retries; } + seastar::future should_retry(std::exception_ptr error, unsigned attempted_retries) const override; }; } // namespace aws