Example #1
0
def _Execute(client, global_endpoint_manager, function, *args, **kwargs):
    """Exectutes the function with passed parameters applying all retry policies

    :param object client:
        Document client instance
    :param object global_endpoint_manager:
        Instance of _GlobalEndpointManager class
    :param function function:
        Function to be called wrapped with retries
    :param (non-keyworded, variable number of arguments list) *args:
    :param (keyworded, variable number of arguments list) **kwargs:

    """
    # instantiate all retry policies here to be applied for each request execution
    endpointDiscovery_retry_policy = endpoint_discovery_retry_policy._EndpointDiscoveryRetryPolicy(global_endpoint_manager)

    resourceThrottle_retry_policy = resource_throttle_retry_policy._ResourceThrottleRetryPolicy(client.connection_policy.RetryOptions.MaxRetryAttemptCount, 
                                                                                                client.connection_policy.RetryOptions.FixedRetryIntervalInMilliseconds, 
                                                                                                client.connection_policy.RetryOptions.MaxWaitTimeInSeconds)
    defaultRetry_policy = default_retry_policy._DefaultRetryPolicy(*args)

    while True:
        try:
            result = _ExecuteFunction(function, *args, **kwargs)

            if not client.last_response_headers:
                client.last_response_headers = {}
            
            # setting the throttle related response headers before returning the result
            client.last_response_headers[HttpHeaders.ThrottleRetryCount] = resourceThrottle_retry_policy.current_retry_attempt_count
            client.last_response_headers[HttpHeaders.ThrottleRetryWaitTimeInMs] = resourceThrottle_retry_policy.cummulative_wait_time_in_milliseconds
            
            return result
        except errors.HTTPFailure as e:
            retry_policy = None

            if (e.status_code == StatusCodes.FORBIDDEN
                    and e.sub_status == SubStatusCodes.WRITE_FORBIDDEN):
                retry_policy = endpointDiscovery_retry_policy
            elif e.status_code == StatusCodes.TOO_MANY_REQUESTS:
                retry_policy = resourceThrottle_retry_policy
            else:
                retry_policy = defaultRetry_policy

            # If none of the retry policies applies or there is no retry needed, set the throttle related response hedaers and 
            # re-throw the exception back
            if not (retry_policy.ShouldRetry(e)):
                if not client.last_response_headers:
                    client.last_response_headers = {}
                client.last_response_headers[HttpHeaders.ThrottleRetryCount] = resourceThrottle_retry_policy.current_retry_attempt_count
                client.last_response_headers[HttpHeaders.ThrottleRetryWaitTimeInMs] = resourceThrottle_retry_policy.cummulative_wait_time_in_milliseconds
                raise
            else:
                # Wait for retry_after_in_milliseconds time before the next retry
                time.sleep(retry_policy.retry_after_in_milliseconds / 1000.0)
def _Execute(client, global_endpoint_manager, function, *args, **kwargs):
    """Exectutes the function with passed parameters applying all retry policies

    :Parameters:
        - `client`: object, document client instance
        - `global_endpoint_manager`: object, instance of _GlobalEndpointManager class
        - `function`: function to be called wrapped with retries
        - `*args`: non-keyworded, variable number of arguments list
        - `**kwargs`: keyworded, variable number of arguments list
    """
    # instantiate all retry policies here to be applied for each request execution
    endpointDiscovery_retry_policy = endpoint_discovery_retry_policy._EndpointDiscoveryRetryPolicy(global_endpoint_manager)

    resourceThrottle_retry_policy = resource_throttle_retry_policy._ResourceThrottleRetryPolicy(client.connection_policy.RetryOptions.MaxRetryAttemptCount, 
                                                                                                client.connection_policy.RetryOptions.FixedRetryIntervalInMilliseconds, 
                                                                                                client.connection_policy.RetryOptions.MaxWaitTimeInSeconds)

    while True:
        try:
            result = _ExecuteFunction(function, *args, **kwargs)

            if not client.last_response_headers:
                client.last_response_headers = {}
            
            # setting the throttle related response headers before returning the result
            client.last_response_headers[http_constants.HttpHeaders.ThrottleRetryCount] = resourceThrottle_retry_policy.current_retry_attempt_count
            client.last_response_headers[http_constants.HttpHeaders.ThrottleRetryWaitTimeInMs] = resourceThrottle_retry_policy.cummulative_wait_time_in_milliseconds
            
            return result
        except errors.HTTPFailure as e:
            retry_policy = None

            if (e.status_code == endpoint_discovery_retry_policy._EndpointDiscoveryRetryPolicy.FORBIDDEN_STATUS_CODE
                    and e.sub_status == endpoint_discovery_retry_policy._EndpointDiscoveryRetryPolicy.WRITE_FORBIDDEN_SUB_STATUS_CODE):
                retry_policy = endpointDiscovery_retry_policy
            elif e.status_code == resource_throttle_retry_policy._ResourceThrottleRetryPolicy.THROTTLE_STATUS_CODE:
                retry_policy = resourceThrottle_retry_policy

            # If none of the retry policies applies or there is no retry needed, set the throttle related response hedaers and 
            # re-throw the exception back
            if not (retry_policy and retry_policy.ShouldRetry(e)):
                if not client.last_response_headers:
                    client.last_response_headers = {}
                client.last_response_headers[http_constants.HttpHeaders.ThrottleRetryCount] = resourceThrottle_retry_policy.current_retry_attempt_count
                client.last_response_headers[http_constants.HttpHeaders.ThrottleRetryWaitTimeInMs] = resourceThrottle_retry_policy.cummulative_wait_time_in_milliseconds
                raise
            else:
                # Wait for retry_after_in_milliseconds time before the next retry
                time.sleep(retry_policy.retry_after_in_milliseconds / 1000.0)