File: retry.py

package info (click to toggle)
azure-data-lake-store-python 1.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 31,952 kB
  • sloc: python: 4,332; makefile: 192
file content (76 lines) | stat: -rw-r--r-- 2,163 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# -*- coding: utf-8 -*-
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------

"""
Provides implementation of different Retry Policies
"""

# standard imports
import logging
import sys
import time
from functools import wraps
# local imports

logger = logging.getLogger(__name__)


class RetryPolicy:
    def should_retry(self, *args):
        pass


class NoRetryPolicy(RetryPolicy):
    def should_retry(self, *args):
        return False


class ExponentialRetryPolicy(RetryPolicy):

    def __init__(self, max_retries=None, exponential_retry_interval=None, exponential_factor=None):
        self.exponential_factor = 4 if exponential_factor is None else exponential_factor
        self.max_retries = 4 if max_retries is None else max_retries
        self.exponential_retry_interval = 1 if exponential_retry_interval is None else exponential_retry_interval

    def should_retry(self, response, last_exception, retry_count):
        if retry_count >= self.max_retries:
            return False

        if last_exception is not None:
            self.__backoff()
            return True

        if response is None:
            return False

        status_code = response.status_code

        if(status_code == 501
            or status_code == 505
            or (300 <= status_code < 500
                and status_code != 401
                and status_code != 408
                and status_code != 429)):
            return False

        if(status_code >= 500
            or status_code == 401
            or status_code == 408
            or status_code == 429
            or status_code == 104):
            self.__backoff()
            return True

        if 100 <= status_code < 300:
            return False

        return False

    def __backoff(self):
        time.sleep(self.exponential_retry_interval)
        self.exponential_retry_interval *= self.exponential_factor