Skip to content

[ PECO - 1768 ] PySQL: adjust HTTP retry logic to align with Go and Nodejs drivers #467

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

Merged
merged 5 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions src/databricks/sql/auth/retry.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,25 +285,27 @@ def sleep_for_retry(self, response: BaseHTTPResponse) -> bool:
"""
retry_after = self.get_retry_after(response)
if retry_after:
backoff = self.get_backoff_time()
proposed_wait = max(backoff, retry_after)
self.check_proposed_wait(proposed_wait)
time.sleep(proposed_wait)
return True
proposed_wait = retry_after
else:
proposed_wait = self.get_exponential_backoff()

return False
proposed_wait = min(proposed_wait, self.delay_max)
self.check_proposed_wait(proposed_wait)
time.sleep(proposed_wait)
return True

def get_backoff_time(self) -> float:
"""Calls urllib3's built-in get_backoff_time.
def get_exponential_backoff(self) -> float:
"""
This method implements the exponential backoff algorithm to calculate the delay between retries.

Never returns a value larger than self.delay_max
A MaxRetryDurationError will be raised if the calculated backoff would exceed self.max_attempts_duration

Note: within urllib3, a backoff is only calculated in cases where a Retry-After header is not present
in the previous unsuccessful request and `self.respect_retry_after_header` is True (which is always true)
:return:
"""

proposed_backoff = super().get_backoff_time()
current_attempt = self.stop_after_attempts_count - self.total
proposed_backoff = (2**current_attempt) * self.delay_min
proposed_backoff = min(proposed_backoff, self.delay_max)
self.check_proposed_wait(proposed_backoff)

Expand Down
4 changes: 2 additions & 2 deletions src/databricks/sql/thrift_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@
# - 900s attempts-duration lines up w ODBC/JDBC drivers (for cluster startup > 10 mins)
_retry_policy = { # (type, default, min, max)
"_retry_delay_min": (float, 1, 0.1, 60),
"_retry_delay_max": (float, 60, 5, 3600),
"_retry_stop_after_attempts_count": (int, 30, 1, 60),
"_retry_delay_max": (float, 30, 5, 3600),
"_retry_stop_after_attempts_count": (int, 5, 1, 60),
"_retry_stop_after_attempts_duration": (float, 900, 1, 86400),
"_retry_delay_default": (float, 5, 1, 60),
}
Expand Down
Loading