Circuit Breaker Pattern
Relevant source files
The following files were used as context for generating this wiki page:
The Circuit Breaker pattern in the flext-tap-oracle-wms project is a resilience mechanism designed to prevent the system from repeatedly attempting operations that are likely to fail, such as calls to a saturated or unresponsive Oracle WMS API. By monitoring for failures, the pattern allows the tap to "trip" the circuit, stopping further requests for a predetermined period to allow the remote system to recover.
This implementation integrates with the flext-oracle-wms client and uses configuration-driven thresholds to manage error handling and validation during data extraction. It is a critical component of the project's Resilience Strategy and is closely tied to Configuration Management.
Resilience Architecture
The architecture relies on the FlextTapOracleWms class and its interaction with the underlying wms_client. The resilience logic is primarily driven by settings defined in FlextTapOracleWmsSettings, which dictate how the client should behave when encountering network or API errors.
Circuit States and Transitions
The project handles various failure states through custom exception handling and client lifecycle management. When a connection or network failure occurs, the system utilizes retry logic and backoff strategies before escalating to a circuit trip.
The flow above illustrates how the tap handles API requests, moving from initial calls to either a successful reset or a progressive failure state that eventually trips the circuit.
Sources: src/flext_tap_oracle_wms/tap.py:220-235, tests/integration/test_functional.py:245-260
Configuration Components
The Circuit Breaker behavior is controlled via specific parameters in the tap configuration. These parameters allow developers to tune the sensitivity of the resilience mechanism based on the specific Oracle WMS environment requirements.
Key Resilience Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
max_retries | Integer | 3 | Maximum number of attempts for a single failed request before tripping. |
retry_delay | Integer | 2 | Delay in seconds between retry attempts. |
timeout | Integer | 30 | Seconds to wait for a response before considering a request timed out. |
enable_rate_limiting | Boolean | True | Whether to throttle requests to prevent overwhelming the API. |
max_requests_per_minute | Integer | 60 | Capacity threshold for rate limiting. |
Sources: src/flext_tap_oracle_wms/tap.py:40-55, src/flext_tap_oracle_wms/settings.py:15-30 (referenced via tap.py flext_config)
Configuration Example
The following JSON structure demonstrates a configuration designed to trigger resilience mechanisms quickly during testing.
{
"base_url": "https://invalid-wms-url.oraclecloud.com",
"username": "test_user",
"password": "test_password",
"max_retries": 1,
"timeout": 5
}
Sources: examples/configs/test_config_circuit_breaker_failure.json:1-7
Error Handling and Validation
When the circuit breaker logic detects a terminal failure (exceeding retry thresholds or encountering a persistent network issue), it raises specific exceptions defined in the project's error hierarchy.
Exception Hierarchy
The FlextTapOracleWmsConfigurationError is the primary exception raised when connectivity cannot be established or configuration prevents a successful circuit recovery.
The hierarchy ensures that resilience-related errors are categorized correctly for the Singer protocol runner.
Sources: src/flext_tap_oracle_wms/errors.py:7-15
Graceful Failure Handling
In test_functional.py, the tap is verified to handle "invalid-url" scenarios by catching OSError or RuntimeError and checking for meaningful error messages related to "connection", "network", or "timeout". This verification ensures the Circuit Breaker logic doesn't crash the entire process but provides a structured failure response.
Sources: tests/integration/test_functional.py:255-275
Implementation Details
The implementation is integrated into the wms_client property of the FlextTapOracleWms class. When the client is instantiated, it receives the timeout and retry_attempts (mapped from max_retries) from the validated settings.
@property
def wms_client(self) -> FlextOracleWmsUtilities.OracleWms.Client:
"""Return a started WMS client instance with resilience settings."""
if self._wms_client is None:
wms_settings = FlextOracleWmsSettings.model_validate({
"base_url": str(self.flext_config.base_url),
"username": self.flext_config.username,
"password": self.flext_config.password.get_secret_value(),
"timeout": float(self.flext_config.timeout),
"retry_attempts": self.flext_config.max_retries,
})
client = FlextOracleWmsUtilities.OracleWms.Client(settings=wms_settings)
start_result = client.start()
if start_result.failure:
msg = start_result.error or "Failed to start Oracle WMS client"
raise FlextTapOracleWmsConfigurationError(msg)
self._wms_client = client
return self._wms_client
Sources: src/flext_tap_oracle_wms/tap.py:165-185
Summary
The Circuit Breaker pattern in flext-tap-oracle-wms serves as a critical shield for the tap, utilizing configuration parameters like max_retries and timeout to manage API volatility. By wrapping the wms_client initialization and API calls in structured error handling, the system ensures that transient network issues are retried, while persistent failures trip the circuit to provide clear, actionable configuration errors.