Skip to content

Commit aea32cc

Browse files
committed
fix: Fix SSE delay reset handling
The default retry policy has exponential backoff with jitter. This retry strategy is reset after some maximum retry interval. Previously, once this reset interval occurred, it would continue to reset every future attempt, effectively disabling the exponential backoff algorithm. This should no longer be the case, as we now reset the baseline used for determine when to reset the strategy each time it is replaced with the base strategy.
1 parent db9f0a2 commit aea32cc

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

ld_eventsource/sse_client.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def __init__(
111111

112112
self.__connection_client = connect.create_client(logger)
113113
self.__connection_result: Optional[ConnectionResult] = None
114-
self.__connected_time: float = 0
114+
self.__retry_reset_baseline: float = 0
115115
self.__disconnected_time: float = 0
116116

117117
self.__closed = False
@@ -248,10 +248,17 @@ def next_retry_delay(self) -> float:
248248
return self.__next_retry_delay
249249

250250
def _compute_next_retry_delay(self):
251-
if self.__retry_delay_reset_threshold > 0 and self.__connected_time != 0:
252-
connection_duration = time.time() - self.__connected_time
251+
# If the __retry_reset_baseline is 0, then we haven't successfully connected yet.
252+
#
253+
# In those situations, we don't want to reset the retry delay strategy;
254+
# it should continue to double until the retry maximum, and then hold
255+
# steady (- jitter).
256+
if self.__retry_delay_reset_threshold > 0 and self.__retry_reset_baseline != 0:
257+
now = time.time()
258+
connection_duration = now - self.__retry_reset_baseline
253259
if connection_duration >= self.__retry_delay_reset_threshold:
254260
self.__current_retry_delay_strategy = self.__base_retry_delay_strategy
261+
self.__retry_reset_baseline = now
255262
self.__next_retry_delay, self.__current_retry_delay_strategy = (
256263
self.__current_retry_delay_strategy.apply(self.__base_retry_delay)
257264
)
@@ -287,7 +294,7 @@ def _try_start(self, can_return_fault: bool) -> Optional[Fault]:
287294
# If can_return_fault is false, it means the caller explicitly called start(), in
288295
# which case there's no way to return a Fault so we just keep retrying transparently.
289296
continue
290-
self.__connected_time = time.time()
297+
self.__retry_reset_baseline = time.time()
291298
self.__current_error_strategy = self.__base_error_strategy
292299
self.__interrupted = False
293300
return None

0 commit comments

Comments
 (0)