-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Labels
enhancementNew feature or requestNew feature or requestrefactoringCode improvement without changing functionalityCode improvement without changing functionalitytechnical-debtTechnical debt that should be addressedTechnical debt that should be addressed
Description
Description
The retry logic is duplicated between the sync client (client.py) and async client (async_client.py), with over 170 lines of nearly identical code. This violates the DRY (Don't Repeat Yourself) principle and makes maintenance harder.
Current State
Both OilPriceAPI (sync) and AsyncOilPriceAPI have nearly identical retry logic with exponential backoff, error handling, and rate limit detection. The only differences are:
time.sleep()vsawait asyncio.sleep()response.json()vsawait response.json()
Proposed Solution
Extract retry logic into a shared strategy class:
class RetryStrategy:
"""Abstract retry logic for both sync and async clients."""
def __init__(self, max_retries: int = 3, retry_on: List[int] = None):
self.max_retries = max_retries
self.retry_on = retry_on or [429, 500, 502, 503, 504]
def should_retry(self, attempt: int, status_code: int) -> bool:
return (
status_code in self.retry_on
and attempt < self.max_retries - 1
)
def wait_time(self, attempt: int) -> float:
return min(2 ** attempt, 60)Benefits
- Single Source of Truth: One place to update retry logic
- Easier Testing: Test retry strategy independently
- Consistency: Guaranteed identical behavior between sync/async
- Maintainability: Changes only need to be made once
Impact
- Breaking Changes: None (internal refactoring only)
- Lines Saved: ~150 lines of duplicated code
- Risk: Low - well-tested functionality
Acceptance Criteria
- Create
RetryStrategyclass in new fileoilpriceapi/retry.py - Update
OilPriceAPIto use strategy - Update
AsyncOilPriceAPIto use strategy - All existing tests pass without modification
- Add unit tests for
RetryStrategyclass
Priority
Low - Quality-of-life improvement for v1.1 or v2.0. Current implementation works correctly.
References
Related files:
oilpriceapi/client.py(lines 163-250)oilpriceapi/async_client.py(lines 120-193)
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestrefactoringCode improvement without changing functionalityCode improvement without changing functionalitytechnical-debtTechnical debt that should be addressedTechnical debt that should be addressed