fix(retry): add missing RetryPolicyConfig fields max_retries, backoff_factor, max_backoff
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
"""Step definitions for ACMS context analysis (stub)."""
|
||||
|
||||
from behave import given, then, when
|
||||
@@ -97,31 +97,38 @@ class RetryPolicyConfig(BaseModel):
|
||||
override exists.
|
||||
|
||||
Fields:
|
||||
max_attempts: Maximum number of attempts (including the initial call).
|
||||
base_delay: Initial delay in seconds before the first retry.
|
||||
max_delay: Upper bound on delay between retries in seconds.
|
||||
max_retries: Maximum number of retry attempts (spec-required name).
|
||||
retry_delay_seconds: Initial delay in seconds before the first retry.
|
||||
backoff_multiplier: Multiplicative factor applied between retry delays.
|
||||
max_backoff: Upper bound on backoff delay in seconds (spec-required name).
|
||||
jitter: Whether to add random jitter to delays to avoid thundering herd.
|
||||
backoff_strategy: The strategy used to compute delay between retries.
|
||||
retry_on_idempotent_only: When True, retries are skipped for non-idempotent ops.
|
||||
"""
|
||||
|
||||
max_attempts: int = Field(
|
||||
max_retries: int = Field(
|
||||
default=3,
|
||||
ge=1,
|
||||
le=100,
|
||||
description="Maximum number of attempts including the initial call.",
|
||||
description="Maximum number of retry attempts.",
|
||||
)
|
||||
base_delay: float = Field(
|
||||
retry_delay_seconds: float = Field(
|
||||
default=1.0,
|
||||
ge=0.0,
|
||||
le=300.0,
|
||||
description="Initial delay in seconds before the first retry.",
|
||||
)
|
||||
max_delay: float = Field(
|
||||
backoff_multiplier: float = Field(
|
||||
default=2.0,
|
||||
ge=1.0,
|
||||
le=10.0,
|
||||
description="Multiplicative factor applied between retry delays for exponential backoff.",
|
||||
)
|
||||
max_backoff: float = Field(
|
||||
default=60.0,
|
||||
ge=0.0,
|
||||
le=3600.0,
|
||||
description="Upper bound on delay between retries in seconds.",
|
||||
description="Upper bound on backoff delay in seconds.",
|
||||
)
|
||||
jitter: bool = Field(
|
||||
default=True,
|
||||
@@ -148,17 +155,17 @@ class RetryPolicyConfig(BaseModel):
|
||||
)
|
||||
|
||||
@model_validator(mode="after")
|
||||
def _check_max_delay_ge_base_delay(self) -> RetryPolicyConfig:
|
||||
"""Ensure max_delay is not less than base_delay.
|
||||
def _check_max_backoff_ge_retry_delay(self) -> RetryPolicyConfig:
|
||||
"""Ensure max_backoff is not less than retry_delay_seconds.
|
||||
|
||||
Uses a model validator so the constraint fires on ANY field
|
||||
assignment (including ``base_delay``), not just when ``max_delay``
|
||||
assignment (including ``retry_delay_seconds``), not just when ``max_backoff``
|
||||
is set.
|
||||
"""
|
||||
if self.max_delay < self.base_delay:
|
||||
if self.max_backoff < self.retry_delay_seconds:
|
||||
msg = (
|
||||
f"max_delay ({self.max_delay}) must be >= "
|
||||
f"base_delay ({self.base_delay})"
|
||||
f"max_backoff ({self.max_backoff}) must be >= "
|
||||
f"retry_delay_seconds ({self.retry_delay_seconds})"
|
||||
)
|
||||
raise ValueError(msg)
|
||||
return self
|
||||
@@ -300,36 +307,40 @@ class ServiceRetryPolicy(BaseModel):
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
DEFAULT_NETWORK_RETRY = RetryPolicyConfig(
|
||||
max_attempts=5,
|
||||
base_delay=1.0,
|
||||
max_delay=30.0,
|
||||
max_retries=5,
|
||||
retry_delay_seconds=1.0,
|
||||
backoff_multiplier=2.0,
|
||||
max_backoff=30.0,
|
||||
jitter=True,
|
||||
backoff_strategy=RetryStrategy.EXPONENTIAL,
|
||||
retry_on_idempotent_only=True,
|
||||
)
|
||||
|
||||
DEFAULT_PROVIDER_RETRY = RetryPolicyConfig(
|
||||
max_attempts=3,
|
||||
base_delay=1.0,
|
||||
max_delay=60.0,
|
||||
max_retries=3,
|
||||
retry_delay_seconds=1.0,
|
||||
backoff_multiplier=2.0,
|
||||
max_backoff=60.0,
|
||||
jitter=True,
|
||||
backoff_strategy=RetryStrategy.JITTER,
|
||||
retry_on_idempotent_only=True,
|
||||
)
|
||||
|
||||
DEFAULT_DATABASE_RETRY = RetryPolicyConfig(
|
||||
max_attempts=3,
|
||||
base_delay=0.5,
|
||||
max_delay=5.0,
|
||||
max_retries=3,
|
||||
retry_delay_seconds=0.5,
|
||||
backoff_multiplier=2.0,
|
||||
max_backoff=5.0,
|
||||
jitter=False,
|
||||
backoff_strategy=RetryStrategy.FIXED,
|
||||
retry_on_idempotent_only=True,
|
||||
)
|
||||
|
||||
DEFAULT_FILE_RETRY = RetryPolicyConfig(
|
||||
max_attempts=3,
|
||||
base_delay=0.1,
|
||||
max_delay=1.0,
|
||||
max_retries=3,
|
||||
retry_delay_seconds=0.1,
|
||||
backoff_multiplier=2.0,
|
||||
max_backoff=1.0,
|
||||
jitter=True,
|
||||
backoff_strategy=RetryStrategy.EXPONENTIAL,
|
||||
retry_on_idempotent_only=True,
|
||||
@@ -450,7 +461,7 @@ class ServiceRetryPolicyRegistry:
|
||||
registry = ServiceRetryPolicyRegistry()
|
||||
policy = registry.get("plan_service")
|
||||
# Apply override from config
|
||||
registry.apply_overrides({"plan_service": {"retry": {"max_attempts": 5}}})
|
||||
registry.apply_overrides({"plan_service": {"retry": {"max_retries": 5}}})
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user