X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/89e091b3ee1fe85a68b0a9a0a619ca7baf606d2d..23f0fc06dbb6d7e82d820a8c65997f32c760f34e:/sdk/python/arvados/retry.py diff --git a/sdk/python/arvados/retry.py b/sdk/python/arvados/retry.py index dccd9c875a..ea4095930f 100644 --- a/sdk/python/arvados/retry.py +++ b/sdk/python/arvados/retry.py @@ -1,5 +1,9 @@ -#!/usr/bin/env python +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 +from builtins import range +from builtins import object import functools import inspect import pycurl @@ -9,7 +13,7 @@ from collections import deque import arvados.errors -_HTTP_SUCCESSES = set(xrange(200, 300)) +_HTTP_SUCCESSES = set(range(200, 300)) _HTTP_CAN_RETRY = set([408, 409, 422, 423, 500, 502, 503, 504]) class RetryLoop(object): @@ -51,7 +55,7 @@ class RetryLoop(object): * save_results: Specify a number to save the last N results that the loop recorded. These records are available through the results attribute, oldest first. Default 1. - * max_wait: Maximum time to wait between retries. + * max_wait: Maximum number of seconds to wait between retries. """ self.tries_left = num_retries + 1 self.check_result = success_check @@ -60,6 +64,7 @@ class RetryLoop(object): self.max_wait = max_wait self.next_start_time = 0 self.results = deque(maxlen=save_results) + self._attempts = 0 self._running = None self._success = None @@ -69,7 +74,7 @@ class RetryLoop(object): def running(self): return self._running and (self._success is None) - def next(self): + def __next__(self): if self._running is None: self._running = True if (self.tries_left < 1) or not self.running(): @@ -97,6 +102,7 @@ class RetryLoop(object): "recorded a loop result after the loop finished") self.results.append(result) self._success = self.check_result(result) + self._attempts += 1 def success(self): """Return the loop's end state. @@ -114,6 +120,19 @@ class RetryLoop(object): raise arvados.errors.AssertionError( "queried loop results before any were recorded") + def attempts(self): + """Return the number of attempts that have been made. + + Includes successes and failures.""" + return self._attempts + + def attempts_str(self): + """Human-readable attempts(): 'N attempts' or '1 attempt'""" + if self._attempts == 1: + return '1 attempt' + else: + return '{} attempts'.format(self._attempts) + def check_http_response_success(status_code): """Convert an HTTP status code to a loop control flag.