diff --git a/docs/config_reference.rst b/docs/config_reference.rst index 25b36dda9..d6c08eb33 100644 --- a/docs/config_reference.rst +++ b/docs/config_reference.rst @@ -1603,19 +1603,24 @@ This handler transmits the whole log record, meaning that all the information wi .. versionadded:: 4.1 -.. py:attribute:: logging.handlers_perflog..httpjson..sleep_intervals - In the case that the http request gets a response 429 (TOO_MANY_REQUESTS), Reframe will cycle over this list of sleep waiting intervals until it gets a different code or exceeds the timeout (when it is set). +.. py:attribute:: logging.handlers_perflog..httpjson..backoff_intervals + + List of wait intervals in seconds when server responds with HTTP error 429 (``TOO_MANY_REQUESTS``). + + In this case, ReFrame will retry contacting the server after waiting an amount of time that is determined by cyclically iterating this list of intervals. + + ReFrame will keep trying contacting the server, until a different HTTP resonse is received (either success or error) or the corresponding :attr:`~config.logging.handlers_perflog..httpjson..timeout` is exceeded. .. versionadded:: 4.7.3 + .. py:attribute:: logging.handlers_perflog..httpjson..timeout - In the case that the http request gets a response 429 (TOO_MANY_REQUESTS), Reframe will keep trying until it succeeds, gets a different error or exceeds the timeout (in seconds). - When this parameter is set to 0, Reframe will keep retrying until it gets a different status code. + Timeout in seconds for retrying when server responds with HTTP error 429 (``TOO_MANY_REQUESTS``). - .. versionadded:: 4.7.3 + .. versionadded:: 4.7.3 .. _exec-mode-config: diff --git a/reframe/core/logging.py b/reframe/core/logging.py index 8b07d613d..4b1c9e048 100644 --- a/reframe/core/logging.py +++ b/reframe/core/logging.py @@ -555,7 +555,7 @@ def _create_httpjson_handler(site_config, config_prefix): json_formatter = site_config.get(f'{config_prefix}/json_formatter') extra_headers = site_config.get(f'{config_prefix}/extra_headers') debug = site_config.get(f'{config_prefix}/debug') - sleep_intervals = site_config.get(f'{config_prefix}/sleep_intervals') + backoff_intervals = site_config.get(f'{config_prefix}/backoff_intervals') timeout = site_config.get(f'{config_prefix}/timeout') parsed_url = urllib.parse.urlparse(url) @@ -598,7 +598,7 @@ def _create_httpjson_handler(site_config, config_prefix): 'no data will be sent to the server') return HTTPJSONHandler(url, extras, ignore_keys, json_formatter, - extra_headers, debug, sleep_intervals, timeout) + extra_headers, debug, backoff_intervals, timeout) def _record_to_json(record, extras, ignore_keys): @@ -648,8 +648,7 @@ class HTTPJSONHandler(logging.Handler): def __init__(self, url, extras=None, ignore_keys=None, json_formatter=None, extra_headers=None, - debug=False, sleep_intervals=[.1, .2, .4, .8, 1.6, 3.2], - timeout=0): + debug=False, backoff_intervals=(1, 2, 3), timeout=0): super().__init__() self._url = url self._extras = extras @@ -674,7 +673,7 @@ def __init__(self, url, extras=None, ignore_keys=None, self._debug = debug self._timeout = timeout - self._sleep_intervals = sleep_intervals + self._backoff_intervals = backoff_intervals def emit(self, record): # Convert tags to a list to make them JSON friendly @@ -695,7 +694,7 @@ def emit(self, record): timeout_time = time.time() + self._timeout try: - sleep_intervals = itertools.cycle(self._sleep_intervals) + backoff_intervals = itertools.cycle(self._backoff_intervals) while True: response = requests.post( self._url, data=json_record, @@ -704,14 +703,9 @@ def emit(self, record): if response.ok: break - if ( - response.status_code == 429 and - ( - not self._timeout or - time.time() < timeout_time - ) - ): - time.sleep(next(sleep_intervals)) + if (response.status_code == 429 and + (not self._timeout or time.time() < timeout_time)): + time.sleep(next(backoff_intervals)) continue raise LoggingError(