Skip to content

Conversation

nishkarsh-db
Copy link

@nishkarsh-db nishkarsh-db commented Aug 29, 2025

What type of PR is this?

  • Refactor
  • Feature
  • Bug Fix
  • Other

Description

Refactored the retry handling mechanism to be idempotency based. Also fixed some tests (which were expecting 404 requests to be retried).

How is this tested?

  • Unit tests
  • E2E Tests
  • Manually
  • N/A

Related Tickets & Documents

Copy link

Thanks for your contribution! To satisfy the DCO policy in our contributing guide every commit message must include a sign-off message. One or more of your commits is missing this message. You can reword previous commit messages with an interactive rebase (git rebase -i main).

@nishkarsh-db nishkarsh-db changed the title added retry handling based on idempotency [PECOBLR-782] added retry handling based on idempotency Aug 29, 2025
Copy link
Contributor

@shivam2680 shivam2680 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks okay overall.
iIs the test coverage already good? Because I don't see any new tests added


# Mapping of CommandType to CommandIdempotency
# Based on the official idempotency classification
COMMAND_IDEMPOTENCY_MAP = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

link the retry design doc section here that classifies requests

CommandType.TELEMETRY_PUSH: CommandIdempotency.IDEMPOTENT,
CommandType.VOLUME_GET: CommandIdempotency.IDEMPOTENT,
CommandType.VOLUME_DELETE: CommandIdempotency.IDEMPOTENT,
CommandType.OTHER: CommandIdempotency.IDEMPOTENT,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what comes under CommandType.OTHER? Please clarify

if not self._is_method_retryable(method):
return False, "Only POST requests are retried"

# Request failed with 404 and was a GetOperationStatus. This is not recoverable. Don't retry.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment mentions Request was a GetOperationStatus but in if condition you're checking for all metadata command types. Is this intended?

return False, "Received code 501 from server."

# Request failed and this method is not retryable. We only retry POST requests.
if not self._is_method_retryable(method):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this method defined?

"CloseOperation received 404 code from Databricks. Cursor is already closed."
)

if status_code in NON_RETRYABLE_STATUS_CODES:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should return more descriptive error message, based on status_code.
eg: UNAUTHORIZED for 403, BAD_REQUEST for 400 etc

before raising an exception
"""
with mocked_server_response(status=404) as mock_obj:
with mocked_server_response(status=429) as mock_obj:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

@shivam2680
Copy link
Contributor

you can run

poetry run python3 -m black src

to fix lint issues

if not rows:
# Read all the rows, row_count should match
self.assertEqual(n, row_count)
assert n == row_count
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this change related to this PR

finally:
# Reset command type after request completion to prevent it from affecting subsequent requests
if isinstance(self._retry_policy, DatabricksRetryPolicy):
self._retry_policy.command_type = None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't setting command_type to NOT_SET better? it will be type safe


try:
# Set command type for OAuth configuration request
self.http_client.setRequestType(CommandType.AUTH)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This again is imposing thread safety concerns. we need to figure out a way to avoid having a state in httpclient.

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.

2 participants