-
Notifications
You must be signed in to change notification settings - Fork 26
[PECOBLR-1219] Added Api retriable codes URL param #1110
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
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 introduces a new URL parameter apiRetriableCodes that enables retrying HTTP requests for specified status codes even when the Retry-After header is absent. When such codes are encountered without a retry header, the system falls back to exponential backoff delay calculation.
Key Changes:
- Added
apiRetriableCodesURL parameter to configure custom retriable HTTP status codes - Modified retry handler logic to use exponential backoff for configured codes when
Retry-Afterheader is missing - Added test coverage for the new retry behavior
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| DatabricksJdbcUrlParams.java | Defines the new API_RETRIABLE_CODES URL parameter with description |
| IDatabricksConnectionContext.java | Adds interface method to retrieve configured API retriable codes |
| DatabricksConnectionContext.java | Implements parsing of comma-separated status codes with error handling |
| DatabricksHttpRetryHandler.java | Implements retry logic using exponential backoff for custom retriable codes |
| DatabricksHttpRetryHandlerTest.java | Adds test verifying retry behavior for 503 status without Retry-After header |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| retryInterval = (int) (calculateExponentialBackoff(executionCount) / 1000); | ||
| } | ||
|
|
Copilot
AI
Nov 27, 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.
This exponential backoff is applied unconditionally for all cases where retryInterval == -1, including status codes not in apiRetriableCodes. The logic should only apply exponential backoff when isInCustomRetriableCodes is true. For other cases with retryInterval == -1, the method should return false as per the existing logic (lines 149-161).
| retryInterval = (int) (calculateExponentialBackoff(executionCount) / 1000); | |
| } | |
| if (isInCustomRetriableCodes) { | |
| retryInterval = (int) (calculateExponentialBackoff(executionCount) / 1000); | |
| } else { | |
| return false; | |
| } | |
| } |
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.
This condition is never reached. And if it reaches (in future) then this will not be a problem.
src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java
Outdated
Show resolved
Hide resolved
src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java
Outdated
Show resolved
Hide resolved
src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java
Show resolved
Hide resolved
src/main/java/com/databricks/jdbc/dbclient/impl/http/DatabricksHttpRetryHandler.java
Outdated
Show resolved
Hide resolved
src/main/java/com/databricks/jdbc/dbclient/impl/http/DatabricksHttpRetryHandler.java
Outdated
Show resolved
Hide resolved
| apiRetriableCodes = connectionContext.getApiRetriableCodes(); | ||
| } | ||
| boolean isInCustomRetriableCodes = | ||
| apiRetriableCodes != null && apiRetriableCodes.contains(statusCode); |
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.
but wouldn't request be already rejected at line 133 (!isStatusCodeRetryable)
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.
In case of 503/429 with no retry-after header, it will not be rejected (unless set in JDBC URL params) as isStatusCodeRetryable just checks the JDBC URL params.
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.
but the new param says apiRetriableCodes which means if i supply 501 to be retried then it should be. it is not specific to 503/429
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.
Ok, so i think the parameter definition could be changed, but i don't think that bypassing the isStatusCodeRetryable check is something we want.
| // Get API retriable codes from connection context | ||
| Set<Integer> apiRetriableCodes = connectionContext.getApiRetriableCodes(); | ||
| boolean isInCustomRetriableCodes = | ||
| apiRetriableCodes != null && apiRetriableCodes.contains(statusCode); |
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.
apiRetriableCodes can never be null?
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.
Yes, It can never be null, So, removed that check.
| "Comma-separated list of HTTP status codes that should be retried even without Retry-After header.", | ||
| ""), | ||
| API_CODES_RETRY_TIMEOUT( | ||
| "ApiCodesRetryTimeout", "Timeout for retrying API retriable codes", "120"); |
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.
Shall we just rename this to ApiRetryTimeout? So that we can use this for some future generic use-cases
| "EnableTokenFederation", "Enable token federation for authentication", "1"); | ||
| "EnableTokenFederation", "Enable token federation for authentication", "1"), | ||
| API_RETRIABLE_CODES( | ||
| "ApiRetriableCodes", |
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.
ApiRetriableHttpCodes
|
|
||
| Set<Integer> retriableCodes = new HashSet<>(); | ||
| for (String code : codes.split(",")) { | ||
| try { |
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.
we should have generic parser, which can be used for parsing Set used elsewhere in this file as well, instead of duplicating code everywhere.
|
|
||
| // check if retry timeout has been hit for custom API retriable codes | ||
| if (apiRetriableCodes.contains(statusCode) | ||
| && statusCode != HttpStatus.SC_SERVICE_UNAVAILABLE |
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.
why this filtering for 403 and 429 here? Why not also include 429 and 503
Description
Testing