Skip to content

Conversation

@nishkarsh-db
Copy link
Collaborator

Description

  • Added a new URL param apiRetriableCodes in order to retry thrift requests even when Retry-After header is not present

Testing

  • Added unit test for the same

Copy link
Contributor

Copilot AI left a 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 apiRetriableCodes URL parameter to configure custom retriable HTTP status codes
  • Modified retry handler logic to use exponential backoff for configured codes when Retry-After header 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.

Comment on lines +165 to +167
retryInterval = (int) (calculateExponentialBackoff(executionCount) / 1000);
}

Copy link

Copilot AI Nov 27, 2025

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).

Suggested change
retryInterval = (int) (calculateExponentialBackoff(executionCount) / 1000);
}
if (isInCustomRetriableCodes) {
retryInterval = (int) (calculateExponentialBackoff(executionCount) / 1000);
} else {
return false;
}
}

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

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.

@nishkarsh-db nishkarsh-db changed the title Added Api retriable codes URL param [PECOBLR-1219] Added Api retriable codes URL param Nov 27, 2025
apiRetriableCodes = connectionContext.getApiRetriableCodes();
}
boolean isInCustomRetriableCodes =
apiRetriableCodes != null && apiRetriableCodes.contains(statusCode);
Copy link
Collaborator

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)

Copy link
Collaborator Author

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.

Copy link
Collaborator

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

Copy link
Collaborator Author

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);
Copy link
Collaborator

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?

Copy link
Collaborator Author

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");
Copy link
Collaborator

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",
Copy link
Collaborator

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 {
Copy link
Collaborator

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
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants