Retry a function. Params: cb: The function to retry. retry_on: A callback that takes the result of the function and returns True if the function should be retried. A function throwing an exception is always retried. wait_plan: A list of waiting
(self, cb, retry_on=None, wait_plan=None)
| 354 | raise NotImplementedError |
| 355 | |
| 356 | def Retry(self, cb, retry_on=None, wait_plan=None): |
| 357 | """ Retry a function. |
| 358 | Params: |
| 359 | cb: The function to retry. |
| 360 | retry_on: A callback that takes the result of the function and returns |
| 361 | True if the function should be retried. A function throwing an |
| 362 | exception is always retried. |
| 363 | wait_plan: A list of waiting delays between retries in seconds. The |
| 364 | maximum number of retries is len(wait_plan). |
| 365 | """ |
| 366 | retry_on = retry_on or (lambda x: False) |
| 367 | wait_plan = list(wait_plan or []) |
| 368 | wait_plan.reverse() |
| 369 | while True: |
| 370 | got_exception = False |
| 371 | try: |
| 372 | result = cb() |
| 373 | except NoRetryException as e: |
| 374 | raise e |
| 375 | except Exception as e: |
| 376 | got_exception = e |
| 377 | if got_exception or retry_on(result): |
| 378 | if not wait_plan: # pragma: no cover |
| 379 | raise Exception("Retried too often. Giving up. Reason: %s" % |
| 380 | str(got_exception)) |
| 381 | wait_time = wait_plan.pop() |
| 382 | print("Waiting for %f seconds." % wait_time) |
| 383 | self._side_effect_handler.Sleep(wait_time) |
| 384 | print("Retrying...") |
| 385 | else: |
| 386 | return result |
| 387 | |
| 388 | def ReadLine(self, default=None): |
| 389 | # Don't prompt in forced mode. |