-
Notifications
You must be signed in to change notification settings - Fork 3
Add tenacity retry library with exponential backoff for network resilience #113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
… resilience Co-authored-by: tjorim <1294876+tjorim@users.noreply.github.com>
|
Important Review skippedBot user detected. To trigger a single review, invoke the You can disable this status message by setting the Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds automatic retry functionality with exponential backoff to handle transient network issues and server errors, enhancing pyrail's reliability in production environments.
- Integrates the tenacity library for intelligent retry logic with exponential backoff
- Implements network error and server error (5xx) retry handling up to 3 attempts
- Preserves existing rate limit handling while adding new resilience features
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| pyrail/irail.py | Adds retry decorator and helper methods for network resilience |
| pyproject.toml | Adds tenacity dependency for retry functionality |
| tests/test_irail.py | Comprehensive test coverage for retry scenarios |
| README.md | Documents new network resilience and retry features |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| @retry( | ||
| stop=stop_after_attempt(3), | ||
| wait=wait_exponential(multiplier=1, min=1, max=10), | ||
| retry=retry_if_exception_type(ClientError), | ||
| reraise=True | ||
| ) |
Copilot
AI
Sep 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The retry decorator configuration creates a potentially confusing API design. The reraise=True parameter will cause the original exception to be raised after all retries are exhausted, but the calling code in _do_request catches ClientError and logs 'Request failed after retries'. This makes it unclear whether the retry logic or the calling method is responsible for final error handling.
| if self._should_retry_on_status(response): | ||
| logger.warning("Server error %d for endpoint %s, will retry", response.status, method) | ||
| # Create a temporary exception to trigger tenacity retry | ||
| raise ClientError(f"Server error {response.status}") |
Copilot
AI
Sep 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creating an artificial exception to trigger the retry mechanism is an anti-pattern that makes the code harder to understand and maintain. Consider using tenacity's retry_if conditions or restructuring the retry logic to handle status codes more naturally rather than converting them to exceptions.
This PR implements automatic retry functionality with exponential backoff to handle transient network issues and server errors, making pyrail more robust and reliable for production use.
Problem
The current implementation only handles rate limiting (429 responses) but doesn't retry on common network failures like connection timeouts, DNS failures, or temporary server errors (5xx). This can lead to unnecessary failures in production environments where transient network issues are common.
Solution
Added the tenacity retry library with intelligent retry logic:
ClientErrorexceptions are automatically retried up to 3 timesExample
The retry logic works transparently - no code changes needed:
When network issues occur, you'll see warning logs showing retry attempts:
Changes Made
tenacitydependency topyproject.toml_execute_http_request()method with@retrydecorator_should_retry_on_status()helper for server error detectionTesting
Added 5 new focused tests covering:
All existing tests continue to pass, ensuring backward compatibility.
Benefits
This enhancement makes pyrail much more suitable for production environments where network resilience is critical.
Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
api.irail.bepython -m pytest tests/ -v --tb=short(dns block)python -m pytest tests/test_irail.py::test_successful_request tests/test_irail.py::test_irail_context_manager tests/test_irail.py::test_date_time_validation tests/test_irail.py::test_error_handling tests/test_irail.py::test_timestamp_to_datetime tests/test_irail.py::test_timestamp_field_deserialization tests/test_irail.py::test_str_to_bool tests/test_irail.py::test_boolean_field_deserialization -v(dns block)If you need me to access, download, or install something from one of these locations, you can either:
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.