coinprices/PriceRetryPolicy.hpp¶
Namespaces¶
| Name |
|---|
| sgns |
Classes¶
| Name | |
|---|---|
| struct | sgns::RetryConfig Fixed retry/backoff schedule (D-12): 1s -> 2s -> (4s, never reached under the default cap of 3 attempts). Tests inject zeros for deterministic zero-backoff runs. |
| class | sgns::RateLimitHoldOff Client-side CoinGecko rate-limit hold-off (D-13): a 429 sets a hold-until timestamp; while held, the CoinGecko tier is skipped entirely (fallback goes straight to the next tier). |
Types¶
| Name | |
|---|---|
| enum class | RetryDecision { Retry, GiveUp} Outcome of a retry decision. |
Functions¶
| Name | |
|---|---|
| bool | IsTransient(const PriceFetchFailure & error) True only for transport-class failures (D-11): timeouts, connection resets, DNS failures. NEVER true for a status-bearing failure (403/429/any HTTP status), parse errors, or input errors. |
| bool | IsTransientTransport(http::ClientError error) Pre-mapping classifier over the transport's own error enum — true for ClientError::TIMEOUT / CONNECT_FAILED / RESOLVE_FAILED only. |
| RetryDecision | ShouldRetry(const PriceFetchFailure & error, int attempt, const RetryConfig & config) Decide whether to make another attempt after a failure. |
Types Documentation¶
enum RetryDecision¶
| Enumerator | Value | Description |
|---|---|---|
| Retry | ||
| GiveUp |
Outcome of a retry decision.
Functions Documentation¶
function IsTransient¶
True only for transport-class failures (D-11): timeouts, connection resets, DNS failures. NEVER true for a status-bearing failure (403/429/any HTTP status), parse errors, or input errors.
function IsTransientTransport¶
Pre-mapping classifier over the transport's own error enum — true for ClientError::TIMEOUT / CONNECT_FAILED / RESOLVE_FAILED only.
function ShouldRetry¶
RetryDecision ShouldRetry(
const PriceFetchFailure & error,
int attempt,
const RetryConfig & config
)
Decide whether to make another attempt after a failure.
Parameters:
- error The failure from the just-finished attempt
- attempt 1-based index of the attempt that just failed
- config The retry schedule in force
Return: Retry iff the error is transient AND attempt < maxAttempts; GiveUp otherwise (403/429 fall through immediately by construction)
Source code¶
#pragma once
#include "PriceFetchError.hpp"
#include <HTTPTypes.hpp>
#include <array>
#include <chrono>
#include <functional>
#include <mutex>
#include <utility>
namespace sgns
{
struct RetryConfig
{
int maxAttempts = 3;
std::array<std::chrono::milliseconds, 3> backoffBeforeRetry{ std::chrono::milliseconds( 1000 ),
std::chrono::milliseconds( 2000 ),
std::chrono::milliseconds( 4000 ) };
};
enum class RetryDecision
{
Retry,
GiveUp
};
bool IsTransient( const PriceFetchFailure &error );
bool IsTransientTransport( http::ClientError error );
RetryDecision ShouldRetry( const PriceFetchFailure &error, int attempt, const RetryConfig &config );
class RateLimitHoldOff
{
public:
using Clock = std::function<std::chrono::system_clock::time_point()>;
explicit RateLimitHoldOff( Clock now = [] { return std::chrono::system_clock::now(); } )
: now_( std::move( now ) )
{
}
void TriggerHoldOff( std::chrono::seconds duration )
{
std::lock_guard<std::mutex> lock( mutex_ );
holdUntil_ = now_() + duration;
}
bool IsHeldOff() const
{
std::lock_guard<std::mutex> lock( mutex_ );
return now_() < holdUntil_;
}
private:
mutable std::mutex mutex_;
std::chrono::system_clock::time_point holdUntil_{};
Clock now_;
};
} // namespace sgns
Updated on 2026-10-09 at 04:02:50 +0000