backon 3.2.0__tar.gz → 3.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {backon-3.2.0 → backon-3.3.0}/PKG-INFO +1 -1
- {backon-3.2.0 → backon-3.3.0}/backon/_common.py +10 -15
- {backon-3.2.0 → backon-3.3.0}/backon/_decorator.py +5 -5
- {backon-3.2.0 → backon-3.3.0}/backon/_retry.py +200 -64
- {backon-3.2.0 → backon-3.3.0}/pyproject.toml +1 -1
- {backon-3.2.0 → backon-3.3.0}/LICENSE +0 -0
- {backon-3.2.0 → backon-3.3.0}/README.md +0 -0
- {backon-3.2.0 → backon-3.3.0}/backon/__init__.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/backon/_async.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/backon/_conditions.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/backon/_jitter.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/backon/_state.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/backon/_sync.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/backon/_typing.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/backon/_wait_gen.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/backon/py.typed +0 -0
- {backon-3.2.0 → backon-3.3.0}/backon/types.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/__init__.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_advanced_features.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_backon.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_backon_async.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_backon_predicate.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_backon_sync.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_features.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_jitter.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_retry.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_types.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_typing.py +0 -0
- {backon-3.2.0 → backon-3.3.0}/tests/test_wait_gen.py +0 -0
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import logging
|
|
3
|
-
import sys
|
|
4
3
|
import time as time_module
|
|
5
|
-
import traceback
|
|
6
4
|
|
|
7
5
|
_logger = logging.getLogger("backon")
|
|
8
6
|
_logger.addHandler(logging.NullHandler())
|
|
@@ -63,6 +61,8 @@ def _prepare_logger(logger):
|
|
|
63
61
|
def _config_handlers(
|
|
64
62
|
user_handlers, *, default_handler=None, logger=None, log_level=None
|
|
65
63
|
):
|
|
64
|
+
if isinstance(user_handlers, list) and logger is None:
|
|
65
|
+
return user_handlers
|
|
66
66
|
handlers = []
|
|
67
67
|
if logger is not None:
|
|
68
68
|
assert log_level is not None
|
|
@@ -84,28 +84,23 @@ def _config_handlers(
|
|
|
84
84
|
|
|
85
85
|
def _log_backoff(details, logger, log_level):
|
|
86
86
|
msg = "Backing off %s(...) for %.1fs (%s)"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
exc_typ, exc, _ = sys.exc_info()
|
|
87
|
+
exc = details.get("exception")
|
|
90
88
|
if exc is not None:
|
|
91
|
-
exc_fmt =
|
|
92
|
-
log_args.append(exc_fmt.rstrip("\n"))
|
|
89
|
+
exc_fmt = f"{type(exc).__name__}: {exc}"
|
|
93
90
|
else:
|
|
94
|
-
|
|
91
|
+
exc_fmt = details.get("value", "unknown")
|
|
92
|
+
log_args = [details["target"].__name__, details["wait"], exc_fmt]
|
|
95
93
|
logger.log(log_level, msg, *log_args)
|
|
96
94
|
|
|
97
95
|
|
|
98
96
|
def _log_giveup(details, logger, log_level):
|
|
99
97
|
msg = "Giving up %s(...) after %d tries (%s)"
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
exc_typ, exc, _ = sys.exc_info()
|
|
98
|
+
exc = details.get("exception")
|
|
103
99
|
if exc is not None:
|
|
104
|
-
exc_fmt =
|
|
105
|
-
log_args.append(exc_fmt.rstrip("\n"))
|
|
100
|
+
exc_fmt = f"{type(exc).__name__}: {exc}"
|
|
106
101
|
else:
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
exc_fmt = details.get("value", "unknown")
|
|
103
|
+
log_args = [details["target"].__name__, details["tries"], exc_fmt]
|
|
109
104
|
logger.log(log_level, msg, *log_args)
|
|
110
105
|
|
|
111
106
|
|
|
@@ -21,7 +21,7 @@ from backon._conditions import (
|
|
|
21
21
|
retry_if_result,
|
|
22
22
|
)
|
|
23
23
|
from backon._jitter import full_jitter
|
|
24
|
-
from backon._retry import
|
|
24
|
+
from backon._retry import _retry_async_inner, _retry_sync_inner
|
|
25
25
|
from backon._state import RetryState
|
|
26
26
|
from backon._typing import (
|
|
27
27
|
P,
|
|
@@ -91,7 +91,7 @@ def on_predicate(
|
|
|
91
91
|
|
|
92
92
|
return cast(
|
|
93
93
|
R,
|
|
94
|
-
await
|
|
94
|
+
await _retry_async_inner(
|
|
95
95
|
wrapped,
|
|
96
96
|
wait_gen,
|
|
97
97
|
condition=condition,
|
|
@@ -121,7 +121,7 @@ def on_predicate(
|
|
|
121
121
|
|
|
122
122
|
return cast(
|
|
123
123
|
R,
|
|
124
|
-
|
|
124
|
+
_retry_sync_inner(
|
|
125
125
|
lambda: target(*args, **kwargs),
|
|
126
126
|
wait_gen,
|
|
127
127
|
condition=condition,
|
|
@@ -217,7 +217,7 @@ def on_exception(
|
|
|
217
217
|
|
|
218
218
|
return cast(
|
|
219
219
|
R,
|
|
220
|
-
await
|
|
220
|
+
await _retry_async_inner(
|
|
221
221
|
wrapped,
|
|
222
222
|
wait_gen,
|
|
223
223
|
condition=condition,
|
|
@@ -247,7 +247,7 @@ def on_exception(
|
|
|
247
247
|
|
|
248
248
|
return cast(
|
|
249
249
|
R,
|
|
250
|
-
|
|
250
|
+
_retry_sync_inner(
|
|
251
251
|
lambda: target(*args, **kwargs),
|
|
252
252
|
wait_gen,
|
|
253
253
|
condition=condition,
|
|
@@ -16,7 +16,6 @@ from backon._common import (
|
|
|
16
16
|
_log_backoff,
|
|
17
17
|
_log_giveup,
|
|
18
18
|
_maybe_call,
|
|
19
|
-
_next_wait,
|
|
20
19
|
_now,
|
|
21
20
|
_prepare_logger,
|
|
22
21
|
is_enabled,
|
|
@@ -44,21 +43,19 @@ from backon._typing import (
|
|
|
44
43
|
from backon._wait_gen import expo
|
|
45
44
|
|
|
46
45
|
|
|
47
|
-
def
|
|
48
|
-
if
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
hdlr(details)
|
|
46
|
+
def _call_hdlrs(hdlrs, details):
|
|
47
|
+
if hdlrs:
|
|
48
|
+
for h in hdlrs:
|
|
49
|
+
h(details)
|
|
52
50
|
|
|
53
51
|
|
|
54
|
-
async def
|
|
55
|
-
if
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
handler(details)
|
|
52
|
+
async def _call_hdlrs_async(handlers, details):
|
|
53
|
+
if handlers:
|
|
54
|
+
for handler in handlers:
|
|
55
|
+
if inspect.iscoroutinefunction(handler):
|
|
56
|
+
await handler(details)
|
|
57
|
+
else:
|
|
58
|
+
handler(details)
|
|
62
59
|
|
|
63
60
|
|
|
64
61
|
def _to_seconds(value: float | int | timedelta) -> float:
|
|
@@ -128,15 +125,16 @@ def _retry_loop_sync(
|
|
|
128
125
|
wait_gen_kwargs,
|
|
129
126
|
):
|
|
130
127
|
state = RetryState(target=target)
|
|
131
|
-
|
|
128
|
+
start_time = _now()
|
|
129
|
+
state.start_time = start_time
|
|
132
130
|
wait = _init_wait_gen(wait_gen, wait_gen_kwargs)
|
|
133
131
|
|
|
134
132
|
while True:
|
|
135
133
|
state.tries += 1
|
|
136
|
-
state.elapsed =
|
|
134
|
+
state.elapsed = _now() - start_time
|
|
137
135
|
outcome = Attempt(tries=state.tries, elapsed=state.elapsed)
|
|
138
136
|
|
|
139
|
-
|
|
137
|
+
_call_hdlrs(on_attempt, state.to_details())
|
|
140
138
|
|
|
141
139
|
try:
|
|
142
140
|
ret = target()
|
|
@@ -145,16 +143,23 @@ def _retry_loop_sync(
|
|
|
145
143
|
outcome.value = None
|
|
146
144
|
state.outcome = outcome
|
|
147
145
|
try:
|
|
148
|
-
|
|
146
|
+
value = wait.send(None)
|
|
147
|
+
if jitter is not None:
|
|
148
|
+
seconds = jitter(value)
|
|
149
|
+
else:
|
|
150
|
+
seconds = value
|
|
151
|
+
if max_time is not None:
|
|
152
|
+
seconds = min(seconds, max_time - state.elapsed)
|
|
149
153
|
except StopIteration:
|
|
150
154
|
break
|
|
151
155
|
if stop(state):
|
|
152
156
|
break
|
|
153
157
|
details = state.to_details()
|
|
154
158
|
details["wait"] = seconds
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
159
|
+
_call_hdlrs(before_sleep, details)
|
|
160
|
+
_call_hdlrs(on_backoff, details)
|
|
161
|
+
if seconds > 0:
|
|
162
|
+
sleep(seconds)
|
|
158
163
|
continue
|
|
159
164
|
except BaseException as exc:
|
|
160
165
|
outcome.exception = exc
|
|
@@ -165,7 +170,7 @@ def _retry_loop_sync(
|
|
|
165
170
|
if not condition(state):
|
|
166
171
|
details = state.to_details()
|
|
167
172
|
details["exception"] = exc
|
|
168
|
-
|
|
173
|
+
_call_hdlrs(on_giveup, details)
|
|
169
174
|
if retry_error_callback is not None:
|
|
170
175
|
return retry_error_callback(details)
|
|
171
176
|
if raise_on_giveup:
|
|
@@ -175,7 +180,7 @@ def _retry_loop_sync(
|
|
|
175
180
|
if stop(state):
|
|
176
181
|
details = state.to_details()
|
|
177
182
|
details["exception"] = exc
|
|
178
|
-
|
|
183
|
+
_call_hdlrs(on_giveup, details)
|
|
179
184
|
if retry_error_callback is not None:
|
|
180
185
|
return retry_error_callback(details)
|
|
181
186
|
if raise_on_giveup:
|
|
@@ -183,11 +188,17 @@ def _retry_loop_sync(
|
|
|
183
188
|
return None
|
|
184
189
|
|
|
185
190
|
try:
|
|
186
|
-
|
|
191
|
+
value = wait.send(exc)
|
|
192
|
+
if jitter is not None:
|
|
193
|
+
seconds = jitter(value)
|
|
194
|
+
else:
|
|
195
|
+
seconds = value
|
|
196
|
+
if max_time is not None:
|
|
197
|
+
seconds = min(seconds, max_time - state.elapsed)
|
|
187
198
|
except StopIteration:
|
|
188
199
|
details = state.to_details()
|
|
189
200
|
details["exception"] = exc
|
|
190
|
-
|
|
201
|
+
_call_hdlrs(on_giveup, details)
|
|
191
202
|
if raise_on_giveup:
|
|
192
203
|
raise exc from None
|
|
193
204
|
return None
|
|
@@ -195,9 +206,10 @@ def _retry_loop_sync(
|
|
|
195
206
|
details = state.to_details()
|
|
196
207
|
details["wait"] = seconds
|
|
197
208
|
details["exception"] = exc
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
209
|
+
_call_hdlrs(before_sleep, details)
|
|
210
|
+
_call_hdlrs(on_backoff, details)
|
|
211
|
+
if seconds > 0:
|
|
212
|
+
sleep(seconds)
|
|
201
213
|
else:
|
|
202
214
|
outcome.value = ret
|
|
203
215
|
outcome.exception = None
|
|
@@ -207,27 +219,34 @@ def _retry_loop_sync(
|
|
|
207
219
|
if stop(state):
|
|
208
220
|
details = state.to_details()
|
|
209
221
|
details["value"] = ret
|
|
210
|
-
|
|
222
|
+
_call_hdlrs(on_giveup, details)
|
|
211
223
|
return ret
|
|
212
224
|
|
|
213
225
|
try:
|
|
214
|
-
|
|
226
|
+
value = wait.send(ret)
|
|
227
|
+
if jitter is not None:
|
|
228
|
+
seconds = jitter(value)
|
|
229
|
+
else:
|
|
230
|
+
seconds = value
|
|
231
|
+
if max_time is not None:
|
|
232
|
+
seconds = min(seconds, max_time - state.elapsed)
|
|
215
233
|
except StopIteration:
|
|
216
234
|
details = state.to_details()
|
|
217
235
|
details["value"] = ret
|
|
218
|
-
|
|
236
|
+
_call_hdlrs(on_giveup, details)
|
|
219
237
|
return ret
|
|
220
238
|
|
|
221
239
|
details = state.to_details()
|
|
222
240
|
details["wait"] = seconds
|
|
223
241
|
details["value"] = ret
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
242
|
+
_call_hdlrs(before_sleep, details)
|
|
243
|
+
_call_hdlrs(on_backoff, details)
|
|
244
|
+
if seconds > 0:
|
|
245
|
+
sleep(seconds)
|
|
227
246
|
else:
|
|
228
247
|
details = state.to_details()
|
|
229
248
|
details["value"] = ret
|
|
230
|
-
|
|
249
|
+
_call_hdlrs(on_success, details)
|
|
231
250
|
return ret
|
|
232
251
|
|
|
233
252
|
|
|
@@ -249,15 +268,16 @@ async def _retry_loop_async(
|
|
|
249
268
|
wait_gen_kwargs,
|
|
250
269
|
):
|
|
251
270
|
state = RetryState(target=target)
|
|
252
|
-
|
|
271
|
+
start_time = _now()
|
|
272
|
+
state.start_time = start_time
|
|
253
273
|
wait = _init_wait_gen(wait_gen, wait_gen_kwargs)
|
|
254
274
|
|
|
255
275
|
while True:
|
|
256
276
|
state.tries += 1
|
|
257
|
-
state.elapsed =
|
|
277
|
+
state.elapsed = _now() - start_time
|
|
258
278
|
outcome = Attempt(tries=state.tries, elapsed=state.elapsed)
|
|
259
279
|
|
|
260
|
-
await
|
|
280
|
+
await _call_hdlrs_async(on_attempt, state.to_details())
|
|
261
281
|
|
|
262
282
|
try:
|
|
263
283
|
ret = await target()
|
|
@@ -266,16 +286,23 @@ async def _retry_loop_async(
|
|
|
266
286
|
outcome.value = None
|
|
267
287
|
state.outcome = outcome
|
|
268
288
|
try:
|
|
269
|
-
|
|
289
|
+
value = wait.send(None)
|
|
290
|
+
if jitter is not None:
|
|
291
|
+
seconds = jitter(value)
|
|
292
|
+
else:
|
|
293
|
+
seconds = value
|
|
294
|
+
if max_time is not None:
|
|
295
|
+
seconds = min(seconds, max_time - state.elapsed)
|
|
270
296
|
except StopIteration:
|
|
271
297
|
break
|
|
272
298
|
if stop(state):
|
|
273
299
|
break
|
|
274
300
|
details = state.to_details()
|
|
275
301
|
details["wait"] = seconds
|
|
276
|
-
await
|
|
277
|
-
await
|
|
278
|
-
|
|
302
|
+
await _call_hdlrs_async(before_sleep, details)
|
|
303
|
+
await _call_hdlrs_async(on_backoff, details)
|
|
304
|
+
if seconds > 0:
|
|
305
|
+
await sleep(seconds)
|
|
279
306
|
continue
|
|
280
307
|
except BaseException as exc:
|
|
281
308
|
outcome.exception = exc
|
|
@@ -286,7 +313,7 @@ async def _retry_loop_async(
|
|
|
286
313
|
if not condition(state):
|
|
287
314
|
details = state.to_details()
|
|
288
315
|
details["exception"] = exc
|
|
289
|
-
await
|
|
316
|
+
await _call_hdlrs_async(on_giveup, details)
|
|
290
317
|
if retry_error_callback is not None:
|
|
291
318
|
return retry_error_callback(details)
|
|
292
319
|
if raise_on_giveup:
|
|
@@ -296,7 +323,7 @@ async def _retry_loop_async(
|
|
|
296
323
|
if stop(state):
|
|
297
324
|
details = state.to_details()
|
|
298
325
|
details["exception"] = exc
|
|
299
|
-
await
|
|
326
|
+
await _call_hdlrs_async(on_giveup, details)
|
|
300
327
|
if retry_error_callback is not None:
|
|
301
328
|
return retry_error_callback(details)
|
|
302
329
|
if raise_on_giveup:
|
|
@@ -304,11 +331,17 @@ async def _retry_loop_async(
|
|
|
304
331
|
return None
|
|
305
332
|
|
|
306
333
|
try:
|
|
307
|
-
|
|
334
|
+
value = wait.send(exc)
|
|
335
|
+
if jitter is not None:
|
|
336
|
+
seconds = jitter(value)
|
|
337
|
+
else:
|
|
338
|
+
seconds = value
|
|
339
|
+
if max_time is not None:
|
|
340
|
+
seconds = min(seconds, max_time - state.elapsed)
|
|
308
341
|
except StopIteration:
|
|
309
342
|
details = state.to_details()
|
|
310
343
|
details["exception"] = exc
|
|
311
|
-
await
|
|
344
|
+
await _call_hdlrs_async(on_giveup, details)
|
|
312
345
|
if raise_on_giveup:
|
|
313
346
|
raise exc from None
|
|
314
347
|
return None
|
|
@@ -316,9 +349,10 @@ async def _retry_loop_async(
|
|
|
316
349
|
details = state.to_details()
|
|
317
350
|
details["wait"] = seconds
|
|
318
351
|
details["exception"] = exc
|
|
319
|
-
await
|
|
320
|
-
await
|
|
321
|
-
|
|
352
|
+
await _call_hdlrs_async(before_sleep, details)
|
|
353
|
+
await _call_hdlrs_async(on_backoff, details)
|
|
354
|
+
if seconds > 0:
|
|
355
|
+
await sleep(seconds)
|
|
322
356
|
else:
|
|
323
357
|
outcome.value = ret
|
|
324
358
|
outcome.exception = None
|
|
@@ -328,30 +362,131 @@ async def _retry_loop_async(
|
|
|
328
362
|
if stop(state):
|
|
329
363
|
details = state.to_details()
|
|
330
364
|
details["value"] = ret
|
|
331
|
-
await
|
|
365
|
+
await _call_hdlrs_async(on_giveup, details)
|
|
332
366
|
return ret
|
|
333
367
|
|
|
334
368
|
try:
|
|
335
|
-
|
|
369
|
+
value = wait.send(ret)
|
|
370
|
+
if jitter is not None:
|
|
371
|
+
seconds = jitter(value)
|
|
372
|
+
else:
|
|
373
|
+
seconds = value
|
|
374
|
+
if max_time is not None:
|
|
375
|
+
seconds = min(seconds, max_time - state.elapsed)
|
|
336
376
|
except StopIteration:
|
|
337
377
|
details = state.to_details()
|
|
338
378
|
details["value"] = ret
|
|
339
|
-
await
|
|
379
|
+
await _call_hdlrs_async(on_giveup, details)
|
|
340
380
|
return ret
|
|
341
381
|
|
|
342
382
|
details = state.to_details()
|
|
343
383
|
details["wait"] = seconds
|
|
344
384
|
details["value"] = ret
|
|
345
|
-
await
|
|
346
|
-
await
|
|
347
|
-
|
|
385
|
+
await _call_hdlrs_async(before_sleep, details)
|
|
386
|
+
await _call_hdlrs_async(on_backoff, details)
|
|
387
|
+
if seconds > 0:
|
|
388
|
+
await sleep(seconds)
|
|
348
389
|
else:
|
|
349
390
|
details = state.to_details()
|
|
350
391
|
details["value"] = ret
|
|
351
|
-
await
|
|
392
|
+
await _call_hdlrs_async(on_success, details)
|
|
352
393
|
return ret
|
|
353
394
|
|
|
354
395
|
|
|
396
|
+
def _retry_sync_inner(
|
|
397
|
+
target,
|
|
398
|
+
wait_gen,
|
|
399
|
+
*,
|
|
400
|
+
condition=None,
|
|
401
|
+
stop=None,
|
|
402
|
+
jitter=None,
|
|
403
|
+
on_success=None,
|
|
404
|
+
on_backoff=None,
|
|
405
|
+
on_giveup=None,
|
|
406
|
+
on_attempt=None,
|
|
407
|
+
before_sleep=None,
|
|
408
|
+
sleep=None,
|
|
409
|
+
retry_error_callback=None,
|
|
410
|
+
raise_on_giveup=True,
|
|
411
|
+
max_time=None,
|
|
412
|
+
wait_gen_kwargs=None,
|
|
413
|
+
max_tries=None,
|
|
414
|
+
):
|
|
415
|
+
if not is_enabled():
|
|
416
|
+
return target()
|
|
417
|
+
if wait_gen_kwargs is None:
|
|
418
|
+
wait_gen_kwargs = {}
|
|
419
|
+
if stop is None:
|
|
420
|
+
stop = _make_default_stop(max_tries, max_time)
|
|
421
|
+
|
|
422
|
+
_sleep = sleep or time_module.sleep
|
|
423
|
+
|
|
424
|
+
return _retry_loop_sync(
|
|
425
|
+
target,
|
|
426
|
+
wait_gen,
|
|
427
|
+
condition,
|
|
428
|
+
stop,
|
|
429
|
+
jitter,
|
|
430
|
+
on_success,
|
|
431
|
+
on_backoff,
|
|
432
|
+
on_giveup,
|
|
433
|
+
on_attempt,
|
|
434
|
+
before_sleep,
|
|
435
|
+
_sleep,
|
|
436
|
+
retry_error_callback,
|
|
437
|
+
raise_on_giveup,
|
|
438
|
+
max_time,
|
|
439
|
+
wait_gen_kwargs,
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
async def _retry_async_inner(
|
|
444
|
+
target,
|
|
445
|
+
wait_gen,
|
|
446
|
+
*,
|
|
447
|
+
condition=None,
|
|
448
|
+
stop=None,
|
|
449
|
+
jitter=None,
|
|
450
|
+
on_success=None,
|
|
451
|
+
on_backoff=None,
|
|
452
|
+
on_giveup=None,
|
|
453
|
+
on_attempt=None,
|
|
454
|
+
before_sleep=None,
|
|
455
|
+
sleep=None,
|
|
456
|
+
retry_error_callback=None,
|
|
457
|
+
raise_on_giveup=True,
|
|
458
|
+
max_time=None,
|
|
459
|
+
wait_gen_kwargs=None,
|
|
460
|
+
max_tries=None,
|
|
461
|
+
):
|
|
462
|
+
if not is_enabled():
|
|
463
|
+
return await target()
|
|
464
|
+
if wait_gen_kwargs is None:
|
|
465
|
+
wait_gen_kwargs = {}
|
|
466
|
+
if stop is None:
|
|
467
|
+
stop = _make_default_stop(max_tries, max_time)
|
|
468
|
+
|
|
469
|
+
_sleep = sleep or asyncio.sleep
|
|
470
|
+
|
|
471
|
+
return await _retry_loop_async(
|
|
472
|
+
target,
|
|
473
|
+
wait_gen,
|
|
474
|
+
condition,
|
|
475
|
+
stop,
|
|
476
|
+
jitter,
|
|
477
|
+
on_success,
|
|
478
|
+
on_backoff,
|
|
479
|
+
on_giveup,
|
|
480
|
+
on_attempt,
|
|
481
|
+
before_sleep,
|
|
482
|
+
_sleep,
|
|
483
|
+
retry_error_callback,
|
|
484
|
+
raise_on_giveup,
|
|
485
|
+
max_time,
|
|
486
|
+
wait_gen_kwargs,
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
|
|
355
490
|
def _retry_sync(
|
|
356
491
|
target: Callable[..., Any],
|
|
357
492
|
wait_gen: _WaitGenerator,
|
|
@@ -721,20 +856,21 @@ class Retrying:
|
|
|
721
856
|
|
|
722
857
|
max_time = _maybe_call(self._max_time)
|
|
723
858
|
try:
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
859
|
+
value = self._iter_wait.send(exc)
|
|
860
|
+
if self._jitter is not None:
|
|
861
|
+
seconds = self._jitter(value)
|
|
862
|
+
else:
|
|
863
|
+
seconds = value
|
|
864
|
+
if max_time is not None:
|
|
865
|
+
seconds = min(seconds, max_time - self._iter_state.elapsed)
|
|
731
866
|
except StopIteration:
|
|
732
867
|
if self._raise_on_giveup:
|
|
733
868
|
raise exc from None
|
|
734
869
|
raise StopIteration from None
|
|
735
870
|
|
|
736
871
|
sleep_fn = self._sleep or time_module.sleep
|
|
737
|
-
|
|
872
|
+
if seconds > 0:
|
|
873
|
+
sleep_fn(seconds)
|
|
738
874
|
|
|
739
875
|
self._iter_state.tries += 1
|
|
740
876
|
self._iter_state.elapsed = _elapsed(self._iter_state.start_time)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|