1818
1919# currently excluded from documentation - see docs/README.md
2020
21- import math
2221import random
2322import time
2423from enum import Enum
2524from typing import Optional , Protocol
2625
27- from ldclient .impl .util import log
26+ from ldclient .config import (
27+ DEFAULT_INITIAL_RECONNECT_DELAY ,
28+ DEFAULT_POLL_INTERVAL
29+ )
30+ from ldclient .impl .util import log , validate_positive_finite
2831
29- # The documented defaults, in seconds. Each stands in for a configured value
30- # that is not a positive, finite number.
31- DEFAULT_STREAMING_INITIAL_RECONNECT_DELAY = 1
32- DEFAULT_STREAMING_MAX_DELAY = 30
33- DEFAULT_POLL_INTERVAL = 30
32+ # The delay ceiling of the normal regime for streaming, in seconds.
33+ NORMAL_STREAMING_CEILING_DELAY = 30
3434
3535# The delay bounds of the extended regime, in seconds. A component enters the
3636# extended regime after an unexpected failure.
3737EXTENDED_INITIAL_DELAY = 5 * 60
38- EXTENDED_MAX_DELAY = 60 * 60
38+ EXTENDED_CEILING_DELAY = 60 * 60
3939
4040# How long streaming must operate without a failure before its retry state
4141# resets, in seconds.
@@ -152,35 +152,37 @@ class RetryState:
152152 def __init__ (
153153 self ,
154154 normal_initial_delay : float ,
155- normal_ceiling : float ,
155+ normal_ceiling_delay : float ,
156156 extended_initial_delay : float ,
157- extended_ceiling : float ,
157+ extended_ceiling_delay : float ,
158158 reset_policy : ResetPolicy ,
159159 operating_cadence : float = 0 ,
160160 ):
161161 """
162162 :param normal_initial_delay: the delay before the first retry in the
163163 normal regime, in seconds
164- :param normal_ceiling: the longest normal-regime delay, in seconds
164+ :param normal_ceiling_delay: the longest normal-regime delay, in
165+ seconds
165166 :param extended_initial_delay: the delay before the first retry in the
166167 extended regime, in seconds
167- :param extended_ceiling: the longest extended-regime delay, in seconds
168+ :param extended_ceiling_delay: the longest extended-regime delay, in
169+ seconds
168170 :param reset_policy: decides when the retry state resets
169171 :param operating_cadence: the wait between healthy operations, in
170172 seconds; no wait is ever shorter than this. Zero for a component
171173 that operates continuously.
172174 """
173175 self ._normal_initial_delay = normal_initial_delay
174- self ._normal_ceiling = normal_ceiling
176+ self ._normal_ceiling_delay = normal_ceiling_delay
175177 self ._extended_initial_delay = extended_initial_delay
176- self ._extended_ceiling = extended_ceiling
178+ self ._extended_ceiling_delay = extended_ceiling_delay
177179 self ._reset_policy = reset_policy
178180 self ._operating_cadence = operating_cadence
179181
180182 self ._n = 0
181183 self ._extended = False
182184 self ._min_delay = self ._normal_initial_delay
183- self ._max_delay = max (self ._normal_ceiling , self ._normal_initial_delay )
185+ self ._max_delay = max (self ._normal_ceiling_delay , self ._normal_initial_delay )
184186 self ._attempts = 0
185187 # Read before any outcome is recorded, this is the ordinary interval.
186188 self ._next_delay = self ._operating_cadence
@@ -212,7 +214,7 @@ def record_failure(self, kind: FailureKind) -> None:
212214 # extended initial delay.
213215 self ._extended = True
214216 self ._min_delay = self ._extended_initial_delay
215- self ._max_delay = max (self ._extended_ceiling , self ._min_delay )
217+ self ._max_delay = max (self ._extended_ceiling_delay , self ._min_delay )
216218 self ._n = 1
217219 else :
218220 self ._n += 1
@@ -245,20 +247,7 @@ def _reset_if_due(self) -> None:
245247 self ._attempts = 0
246248 self ._extended = False
247249 self ._min_delay = self ._normal_initial_delay
248- self ._max_delay = max (self ._normal_ceiling , self ._normal_initial_delay )
249-
250-
251- def _positive_finite (value : float , default : float , name : str ) -> float :
252- """Returns ``value`` if it is a positive, finite number of seconds, and the
253- default otherwise. A non-finite value would make the jitter arithmetic
254- produce a NaN delay, and a non-positive one would retry with no wait."""
255- if value > 0 and math .isfinite (value ):
256- return value
257- log .warning (
258- "%s must be a positive, finite number of seconds; using the default of %ss"
259- % (name , default )
260- )
261- return default
250+ self ._max_delay = max (self ._normal_ceiling_delay , self ._normal_initial_delay )
262251
263252
264253def for_streaming (initial_reconnect_delay : float ) -> RetryState :
@@ -276,14 +265,14 @@ def for_streaming(initial_reconnect_delay: float) -> RetryState:
276265
277266 The extended regime never starts below the configured delay.
278267 """
279- initial_reconnect_delay = _positive_finite (
280- initial_reconnect_delay , DEFAULT_STREAMING_INITIAL_RECONNECT_DELAY , 'initial_reconnect_delay'
268+ initial_reconnect_delay = validate_positive_finite (
269+ initial_reconnect_delay , DEFAULT_INITIAL_RECONNECT_DELAY , 'initial_reconnect_delay' , log
281270 )
282271 return RetryState (
283272 normal_initial_delay = initial_reconnect_delay ,
284- normal_ceiling = DEFAULT_STREAMING_MAX_DELAY ,
273+ normal_ceiling_delay = NORMAL_STREAMING_CEILING_DELAY ,
285274 extended_initial_delay = max (EXTENDED_INITIAL_DELAY , initial_reconnect_delay ),
286- extended_ceiling = EXTENDED_MAX_DELAY ,
275+ extended_ceiling_delay = EXTENDED_CEILING_DELAY ,
287276 reset_policy = AfterHealthyFor (STREAMING_RESET_INTERVAL ),
288277 operating_cadence = 0
289278 )
@@ -302,12 +291,12 @@ def for_polling(poll_interval: float) -> RetryState:
302291 ``Config`` clamps the poll interval, but the documented default stands in
303292 for anything that reaches here and is not a positive, finite number.
304293 """
305- poll_interval = _positive_finite (poll_interval , DEFAULT_POLL_INTERVAL , 'poll_interval' )
294+ poll_interval = validate_positive_finite (poll_interval , DEFAULT_POLL_INTERVAL , 'poll_interval' , log )
306295 return RetryState (
307296 normal_initial_delay = poll_interval ,
308- normal_ceiling = poll_interval ,
297+ normal_ceiling_delay = poll_interval ,
309298 extended_initial_delay = max (EXTENDED_INITIAL_DELAY , poll_interval ),
310- extended_ceiling = EXTENDED_MAX_DELAY ,
299+ extended_ceiling_delay = EXTENDED_CEILING_DELAY ,
311300 reset_policy = AfterConsecutiveSuccesses (POLLING_RESET_SUCCESSES ),
312301 operating_cadence = poll_interval ,
313302 )
0 commit comments