@@ -45,17 +45,36 @@ class HubstorageClient(object):
45
45
DEFAULT_ENDPOINT = 'http://storage.scrapinghub.com/'
46
46
USERAGENT = 'python-hubstorage/{0}' .format (__version__ )
47
47
48
- DEFAULT_TIMEOUT = 60.0
49
- RETRY_EXPONENTIAL_BACKOFF_MS = 500
50
- RETRY_JITTER_MS = 500
48
+ DEFAULT_CONNECTION_TIMEOUT_S = 60.0
49
+ RETRY_DEFAUT_MAX_RETRY_TIME_S = 60.0
51
50
52
- def __init__ (self , auth = None , endpoint = None , connection_timeout = None ,
53
- max_retries = 3 ):
51
+ RETRY_DEFAULT_MAX_RETRIES = 3
52
+ RETRY_DEFAULT_JITTER_MS = 500
53
+ RETRY_DEFAULT_EXPONENTIAL_BACKOFF_MS = 500
54
+
55
+ def __init__ (self , auth = None , endpoint = None , connection_timeout = None , max_retries = None , max_retry_time = None ):
56
+ """
57
+ Note:
58
+ max_retries and max_retry_time change how the client attempt to retry failing requests that are
59
+ idempotent (safe to execute multiple time).
60
+
61
+ HubstorageClient(max_retries=3) will retry requests 3 times, no matter the time it takes.
62
+ Use max_retry_time if you want to bound the time spent in retrying.
63
+
64
+ By default, requests are retried at most 3 times, during 60 seconds.
65
+
66
+ Args:
67
+ auth (str): The client authentication token
68
+ endpoint (str): The API root address
69
+ connection_timeout (int): The connection timeout for a _single request_
70
+ max_retries (int): The number of time idempotent requests may be retried
71
+ max_retry_time (int): The time, in seconds, during which the client can retry a request
72
+ """
54
73
self .auth = xauth (auth )
55
74
self .endpoint = endpoint or self .DEFAULT_ENDPOINT
56
- self .connection_timeout = connection_timeout or self .DEFAULT_TIMEOUT
75
+ self .connection_timeout = connection_timeout or self .DEFAULT_CONNECTION_TIMEOUT_S
57
76
self .session = self ._create_session ()
58
- self .retrier = self ._create_retrier (max_retries , self . RETRY_EXPONENTIAL_BACKOFF_MS , self . RETRY_JITTER_MS )
77
+ self .retrier = self ._create_retrier (max_retries , max_retry_time )
59
78
self .jobq = JobQ (self , None )
60
79
self .projects = Projects (self , None )
61
80
self .root = ResourceType (self , None )
@@ -81,11 +100,32 @@ def invoke_request():
81
100
else :
82
101
return invoke_request ()
83
102
84
- def _create_retrier (self , max_retries , exponential_backoff , jitter ):
85
- return Retrying (stop_max_attempt_number = max_retries + 1 ,
103
+ def _create_retrier (self , max_retries , max_retry_time ):
104
+ """
105
+ Create the Retrier object used to process idempotent client requests.
106
+
107
+ If only max_retries is set, the default max_retry_time is ignored.
108
+
109
+ Args:
110
+ max_retries (int): the number of retries to be attempted
111
+ max_retry_time (int): the number of time, in seconds, to retry for.
112
+ Returns:
113
+ A Retrying instance, that implements a call(func) method.
114
+ """
115
+
116
+ # Client sets max_retries only
117
+ if max_retries is not None and max_retry_time is None :
118
+ stop_max_delay = None
119
+ stop_max_attempt_number = max_retries + 1
120
+ else :
121
+ stop_max_delay = (max_retry_time or self .RETRY_DEFAUT_MAX_RETRY_TIME_S ) * 1000.0
122
+ stop_max_attempt_number = (max_retries or self .RETRY_DEFAULT_MAX_RETRIES ) + 1
123
+
124
+ return Retrying (stop_max_attempt_number = stop_max_attempt_number ,
125
+ stop_max_delay = stop_max_delay ,
86
126
retry_on_exception = _hc_retry_on_exception ,
87
- wait_exponential_multiplier = exponential_backoff ,
88
- wait_jitter_max = jitter )
127
+ wait_exponential_multiplier = self . RETRY_DEFAULT_EXPONENTIAL_BACKOFF_MS ,
128
+ wait_jitter_max = self . RETRY_DEFAULT_JITTER_MS )
89
129
90
130
def _create_session (self ):
91
131
s = session ()
0 commit comments