in source/lambda/boto_retry/aws_service_retry.py [0:0]
def call(self, boto_client_or_resource, method_name, call_arguments):
"""
Calls the original boto3 methods that is wrapped in the retry logic
:param boto_client_or_resource: Boto3 client or resource instance
:param method_name: Name of the wrapped method with retries
:param call_arguments: Boto3 method parameters
:return: result of the wrapped boto3 method
"""
def timed_out_by_specified_timeout(start_time, time_now, next_wait):
if self._timeout is None:
return False
return (time_now - start_time) > (self._timeout - next_wait)
def timed_out_by_lambda_timeout(next_wait):
if self._context is None:
return False
context_seconds_left = self._context.get_remaining_time_in_millis() * 1000
return context_seconds_left < self._lambda_time_out_margin + next_wait
start = time()
# gets the method with the retry logic
method = getattr(boto_client_or_resource, method_name)
# reset wait time strategy
self._wait_strategy.reset()
retries = 0
for wait_until_next_retry in self._wait_strategy:
try:
# make the "wrapped" call
if boto_retry.boto_retry_debug:
t = time()
dt = datetime.fromtimestamp(t)
print(boto_retry.LOG_FORMAT.format(dt.year, dt.month, dt.day, dt.hour, dt.minute,
dt.second, str(dt.microsecond)[0:3], method_name, retries))
retries += 1
resp = method(**call_arguments)
# no exceptions, just return result
return resp
except Exception as ex:
# there was an exception
now = time()
# test if there should be a retry based on the type of the exception
if self.can_retry(ex):
# test if there is enough time left for the next retry, if not raise the exception
if timed_out_by_specified_timeout(start, now, wait_until_next_retry) or \
timed_out_by_lambda_timeout(wait_until_next_retry):
raise Exception("Call {} timed out, last exception was {}".format(method_name, ex))
else:
# else wait until next retry
sleep(wait_until_next_retry)
continue
else:
# No recovery for this type of exception
raise ex