def increment(self, settings, request, response=None, error=None, **kwargs): # pylint:disable=unused-argument, arguments-differ # type: (...)->None """Increment the retry counters. :param Any request: :param dict settings: :param Any response: A pipeline response object. :param Any error: An error encountered during the request, or None if the response was received successfully. :keyword callable cls: A custom type or function that will be passed the direct response :return: Whether the retry attempts are exhausted. :rtype: None """ settings["total"] -= 1 if error and isinstance(error, ServiceRequestError): # Errors when we're fairly sure that the server did not receive the # request, so it should be safe to retry. settings["connect"] -= 1 settings["history"].append(RequestHistory(request, error=error)) elif error and isinstance(error, ServiceResponseError): # Errors that occur after the request has been started, so we should # assume that the server began processing it. settings["read"] -= 1 settings["history"].append(RequestHistory(request, error=error)) else: # Incrementing because of a server error like a 500 in # status_forcelist and a the given method is in the whitelist if response: settings["status"] -= 1 settings["history"].append( RequestHistory(request, http_response=response)) if not is_exhausted(settings): if request.method not in ["PUT"] and settings["retry_secondary"]: self._set_next_host_location(settings, request) # rewind the request body if it is a stream if request.body and hasattr(request.body, "read"): # no position was saved, then retry would not work if settings["body_position"] is None: return False try: # attempt to rewind the body to the initial position request.body.seek(settings["body_position"], SEEK_SET) except (UnsupportedOperation, ValueError): # if body is not seekable, then retry would not work return False settings["count"] += 1 return True return False
def increment(self, settings, request, response=None, error=None): """Increment the retry counters. :param response: A pipeline response object. :param error: An error encountered during the request, or None if the response was received successfully. :return: Whether the retry attempts are exhausted. """ settings['total'] -= 1 if error and isinstance(error, ServiceRequestError): # Errors when we're fairly sure that the server did not receive the # request, so it should be safe to retry. settings['connect'] -= 1 settings['history'].append(RequestHistory(request, error=error)) elif error and isinstance(error, ServiceResponseError): # Errors that occur after the request has been started, so we should # assume that the server began processing it. settings['read'] -= 1 settings['history'].append(RequestHistory(request, error=error)) else: # Incrementing because of a server error like a 500 in # status_forcelist and a the given method is in the allowlist if response: settings['status'] -= 1 settings['history'].append( RequestHistory(request, http_response=response)) if not is_exhausted(settings): if request.method not in ['PUT'] and settings['retry_secondary']: self._set_next_host_location(settings, request) # rewind the request body if it is a stream if request.body and hasattr(request.body, 'read'): # no position was saved, then retry would not work if settings['body_position'] is None: return False try: # attempt to rewind the body to the initial position request.body.seek(settings['body_position'], SEEK_SET) except (UnsupportedOperation, ValueError): # if body is not seekable, then retry would not work return False settings['count'] += 1 return True return False
def test_request_history(): class Non_deep_copiable(object): def __deepcopy__(self, memodict={}): raise ValueError() body = Non_deep_copiable() request = HttpRequest('GET', 'http://localhost/', {'user-agent': 'test_request_history'}) request.body = body request_history = RequestHistory(request) assert request_history.http_request.headers == request.headers assert request_history.http_request.url == request.url assert request_history.http_request.method == request.method