Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: infra_libs/httplib2_utils.py

Issue 2114073002: Add HttpsMonitor (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Fix coverage Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « infra_libs/__init__.py ('k') | infra_libs/test/httplib2_utils_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import collections 5 import collections
6 import copy 6 import copy
7 import json 7 import json
8 import logging 8 import logging
9 import os 9 import os
10 import re 10 import re
11 import socket 11 import socket
12 import sys 12 import sys
13 import time 13 import time
14 14
15 import httplib2 15 import httplib2
16 import oauth2client.client 16 import oauth2client.client
17 17
18 from googleapiclient import errors
18 from infra_libs.ts_mon.common import http_metrics 19 from infra_libs.ts_mon.common import http_metrics
19 20
20 DEFAULT_SCOPES = ['email'] 21 DEFAULT_SCOPES = ['email']
21 22
22 # default timeout for http requests, in seconds 23 # default timeout for http requests, in seconds
23 DEFAULT_TIMEOUT = 30 24 DEFAULT_TIMEOUT = 30
24 25
25 # This is part of the API. 26 # This is part of the API.
26 if sys.platform.startswith('win'): # pragma: no cover 27 if sys.platform.startswith('win'): # pragma: no cover
27 SERVICE_ACCOUNTS_CREDS_ROOT = 'C:\\creds\\service_accounts' 28 SERVICE_ACCOUNTS_CREDS_ROOT = 'C:\\creds\\service_accounts'
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 credentials_filename, 155 credentials_filename,
155 scope=scope, 156 scope=scope,
156 service_accounts_creds_root=service_accounts_creds_root) 157 service_accounts_creds_root=service_accounts_creds_root)
157 158
158 if http_identifier: 159 if http_identifier:
159 http = InstrumentedHttp(http_identifier, timeout=timeout) 160 http = InstrumentedHttp(http_identifier, timeout=timeout)
160 else: 161 else:
161 http = httplib2.Http(timeout=timeout) 162 http = httplib2.Http(timeout=timeout)
162 return creds.authorize(http) 163 return creds.authorize(http)
163 164
165 class RetriableHttp(httplib2.Http):
166 """A httplib2.Http object that retries on failure."""
167
168 def __init__(self, max_tries=5, retrying_statuses_fn=None, **kwargs):
169 """
170 Args:
171 http_obj: an httplib2.Http instance
172 max_tries: a number of maximum tries
173 retrying_statuses_fn: a function that returns True if a given status
174 should be retried
175 """
176 super(RetriableHttp, self).__init__(**kwargs)
177 self._max_tries = max_tries
178 self._retrying_statuses_fn = retrying_statuses_fn or \
179 set(range(500,599)).__contains__
180
181 def request(self, uri, method='GET', body=None, *args, **kwargs):
182 for i in range(1, self._max_tries + 1):
183 try:
184 response, content = super(RetriableHttp, self).request(
185 uri, method, body, *args, **kwargs)
186
187 if self._retrying_statuses_fn(response.status):
188 logging.info('RetriableHttp: attempt %d receiving status %d, %s',
189 i, response.status,
190 'final attempt' if i == self._max_tries else \
191 'will retry')
192 else:
193 break
194 except (ValueError, errors.Error,
195 socket.timeout, socket.error, socket.herror, socket.gaierror,
196 httplib2.HttpLib2Error) as error:
197 logging.info('RetriableHttp: attempt %d received exception: %s, %s',
198 i, error, 'final attempt' if i == self._max_tries else \
199 'will retry')
200 if i == self._max_tries:
201 raise
202
203 return response, content
204
164 205
165 class InstrumentedHttp(httplib2.Http): 206 class InstrumentedHttp(httplib2.Http):
166 """A httplib2.Http object that reports ts_mon metrics about its requests.""" 207 """A httplib2.Http object that reports ts_mon metrics about its requests."""
167 208
168 def __init__(self, name, time_fn=time.time, timeout=DEFAULT_TIMEOUT, 209 def __init__(self, name, time_fn=time.time, timeout=DEFAULT_TIMEOUT,
169 **kwargs): 210 **kwargs):
170 """ 211 """
171 Args: 212 Args:
172 name: An identifier for the HTTP requests made by this object. 213 name: An identifier for the HTTP requests made by this object.
173 time_fn: Function returning the current time in seconds. Use for testing 214 time_fn: Function returning the current time in seconds. Use for testing
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 self.requests_made.append(self.HttpCall(uri, method, body, headers)) 298 self.requests_made.append(self.HttpCall(uri, method, body, headers))
258 headers = None 299 headers = None
259 body = None 300 body = None
260 for candidate in self._uris: 301 for candidate in self._uris:
261 if candidate[0].match(uri): 302 if candidate[0].match(uri):
262 _, headers, body = candidate 303 _, headers, body = candidate
263 break 304 break
264 if not headers: 305 if not headers:
265 raise AssertionError("Unexpected request to %s" % uri) 306 raise AssertionError("Unexpected request to %s" % uri)
266 return httplib2.Response(headers), body 307 return httplib2.Response(headers), body
OLDNEW
« no previous file with comments | « infra_libs/__init__.py ('k') | infra_libs/test/httplib2_utils_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698