-
Notifications
You must be signed in to change notification settings - Fork 32
fix: use seconds for retry backoff and fix refresh_secret_now datetime math #72
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: master
Are you sure you want to change the base?
Changes from all commits
e1294b9
c87f6be
eb6f164
a9140a0
d097c7e
2d1f198
af33a1d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -97,14 +97,15 @@ def __refresh(self): | |
| self._set_result(self._execute_refresh()) | ||
| self._exception = None | ||
| self._exception_count = 0 | ||
| self._next_retry_time = None | ||
| except Exception as e: # pylint: disable=broad-except | ||
| self._exception = e | ||
| delay = self._config.exception_retry_delay_base * ( | ||
| self._config.exception_retry_growth_factor ** self._exception_count | ||
| ) | ||
| self._exception_count += 1 | ||
| delay = min(delay, self._config.exception_retry_delay_max) | ||
| self._next_retry_time = datetime.now(timezone.utc) + timedelta(milliseconds=delay) | ||
| self._next_retry_time = datetime.now(timezone.utc) + timedelta(seconds=delay) | ||
|
|
||
| def get_secret_value(self, version_stage=None): | ||
| """Get the cached secret value for the given version stage. | ||
|
|
@@ -134,15 +135,18 @@ def refresh_secret_now(self): | |
| # Generate a random number to have a sleep jitter to not get stuck in a retry loop | ||
| sleep = randint(int(self.FORCE_REFRESH_JITTER_SLEEP / 2), self.FORCE_REFRESH_JITTER_SLEEP + 1) | ||
|
|
||
| if self._exception is not None: | ||
| current_time_millis = int(datetime.now(timezone.utc).timestamp() * 1000) | ||
| exception_sleep = self._next_retry_time - current_time_millis | ||
| if self._exception is not None and self._next_retry_time is not None: | ||
| now = datetime.now(timezone.utc) | ||
| exception_sleep = (self._next_retry_time - now).total_seconds() * 1000 | ||
| sleep = max(exception_sleep, sleep) | ||
|
|
||
| # Divide by 1000 for millis | ||
| time.sleep(sleep / 1000) | ||
|
|
||
| self._execute_refresh() | ||
| # Refresh under the lock: __refresh stores the result and resets exception/backoff | ||
| # state on success, or records the exception and schedules a retry on failure. | ||
| with self._lock: | ||
| self.__refresh() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we opted for the If we pull inspiration from the Java caching library, it uses a bool to signal to the customer whether a refresh successful or not. I think this is a decent approach, what do you think? |
||
|
|
||
| def _get_result(self): | ||
| """Get the stored result using a hook if present""" | ||
|
|
||
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.
A minor issue here - exception sleep can be negative which Ideally should be 0 if next_retry_time hasn't been reached yet. The PR description captures the change as
Which doesn't match the implementation.
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.
I think this is okay since we have
sleep = max(exception_sleep, sleep)which will always be at a minimum of line 135.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.
+1. For the minimum number it will choose the random number. I had that line in the code before, but then saw sleep = max(exception_sleep, sleep) and then removed it.