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

Side by Side Diff: rietveld.py

Issue 350433003: Retry fetching patch from rietveld on a 404 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Move to _send() Created 6 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # coding: utf-8 1 # coding: utf-8
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 """Defines class Rietveld to easily access a rietveld instance. 5 """Defines class Rietveld to easily access a rietveld instance.
6 6
7 Security implications: 7 Security implications:
8 8
9 The following hypothesis are made: 9 The following hypothesis are made:
10 - Rietveld enforces: 10 - Rietveld enforces:
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 90
91 Converts any CRLF into LF and strip extraneous whitespace. 91 Converts any CRLF into LF and strip extraneous whitespace.
92 """ 92 """
93 return '\n'.join(self.get('/%d/description' % issue).strip().splitlines()) 93 return '\n'.join(self.get('/%d/description' % issue).strip().splitlines())
94 94
95 def get_issue_properties(self, issue, messages): 95 def get_issue_properties(self, issue, messages):
96 """Returns all the issue's metadata as a dictionary.""" 96 """Returns all the issue's metadata as a dictionary."""
97 url = '/api/%d' % issue 97 url = '/api/%d' % issue
98 if messages: 98 if messages:
99 url += '?messages=true' 99 url += '?messages=true'
100 data = json.loads(self.get(url)) 100 data = json.loads(self.get(url, retry_on_404=True))
101 data['description'] = '\n'.join(data['description'].strip().splitlines()) 101 data['description'] = '\n'.join(data['description'].strip().splitlines())
102 return data 102 return data
103 103
104 def get_patchset_properties(self, issue, patchset): 104 def get_patchset_properties(self, issue, patchset):
105 """Returns the patchset properties.""" 105 """Returns the patchset properties."""
106 url = '/api/%d/%d' % (issue, patchset) 106 url = '/api/%d/%d' % (issue, patchset)
107 return json.loads(self.get(url)) 107 return json.loads(self.get(url))
108 108
109 def get_file_content(self, issue, patchset, item): 109 def get_file_content(self, issue, patchset, item):
110 """Returns the content of a new file. 110 """Returns the content of a new file.
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 return data['jobs'], data['cursor'] 382 return data['jobs'], data['cursor']
383 383
384 def get(self, request_path, **kwargs): 384 def get(self, request_path, **kwargs):
385 kwargs.setdefault('payload', None) 385 kwargs.setdefault('payload', None)
386 return self._send(request_path, **kwargs) 386 return self._send(request_path, **kwargs)
387 387
388 def post(self, request_path, data, **kwargs): 388 def post(self, request_path, data, **kwargs):
389 ctype, body = upload.EncodeMultipartFormData(data, []) 389 ctype, body = upload.EncodeMultipartFormData(data, [])
390 return self._send(request_path, payload=body, content_type=ctype, **kwargs) 390 return self._send(request_path, payload=body, content_type=ctype, **kwargs)
391 391
392 def _send(self, request_path, **kwargs): 392 def _send(self, request_path, retry_on_404=False, **kwargs):
393 """Sends a POST/GET to Rietveld. Returns the response body.""" 393 """Sends a POST/GET to Rietveld. Returns the response body."""
394 # rpc_server.Send() assumes timeout=None by default; make sure it's set 394 # rpc_server.Send() assumes timeout=None by default; make sure it's set
395 # to something reasonable. 395 # to something reasonable.
396 kwargs.setdefault('timeout', 15) 396 kwargs.setdefault('timeout', 15)
397 logging.debug('POSTing to %s, args %s.', request_path, kwargs) 397 logging.debug('POSTing to %s, args %s.', request_path, kwargs)
398 try: 398 try:
399 # Sadly, upload.py calls ErrorExit() which does a sys.exit(1) on HTTP 399 # Sadly, upload.py calls ErrorExit() which does a sys.exit(1) on HTTP
400 # 500 in AbstractRpcServer.Send(). 400 # 500 in AbstractRpcServer.Send().
401 old_error_exit = upload.ErrorExit 401 old_error_exit = upload.ErrorExit
402 def trap_http_500(msg): 402 def trap_http_500(msg):
(...skipping 10 matching lines...) Expand all
413 for retry in xrange(maxtries): 413 for retry in xrange(maxtries):
414 try: 414 try:
415 logging.debug('%s' % request_path) 415 logging.debug('%s' % request_path)
416 result = self.rpc_server.Send(request_path, **kwargs) 416 result = self.rpc_server.Send(request_path, **kwargs)
417 # Sometimes GAE returns a HTTP 200 but with HTTP 500 as the content. 417 # Sometimes GAE returns a HTTP 200 but with HTTP 500 as the content.
418 # How nice. 418 # How nice.
419 return result 419 return result
420 except urllib2.HTTPError, e: 420 except urllib2.HTTPError, e:
421 if retry >= (maxtries - 1): 421 if retry >= (maxtries - 1):
422 raise 422 raise
423 if e.code not in (500, 502, 503): 423 flake_codes = [500, 502, 503]
424 if retry_on_404:
425 flake_codes.append(404)
426 if e.code not in flake_codes:
424 raise 427 raise
425 except urllib2.URLError, e: 428 except urllib2.URLError, e:
426 if retry >= (maxtries - 1): 429 if retry >= (maxtries - 1):
427 raise 430 raise
428 if (not 'Name or service not known' in e.reason and 431 if (not 'Name or service not known' in e.reason and
429 not 'EOF occurred in violation of protocol' in e.reason): 432 not 'EOF occurred in violation of protocol' in e.reason):
430 # Usually internal GAE flakiness. 433 # Usually internal GAE flakiness.
431 raise 434 raise
432 except ssl.SSLError, e: 435 except ssl.SSLError, e:
433 if retry >= (maxtries - 1): 436 if retry >= (maxtries - 1):
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 def trigger_try_jobs( # pylint:disable=R0201 720 def trigger_try_jobs( # pylint:disable=R0201
718 self, issue, patchset, reason, clobber, revision, builders_and_tests, 721 self, issue, patchset, reason, clobber, revision, builders_and_tests,
719 master=None): 722 master=None):
720 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' % 723 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' %
721 (builders_and_tests, issue)) 724 (builders_and_tests, issue))
722 725
723 def trigger_distributed_try_jobs( # pylint:disable=R0201 726 def trigger_distributed_try_jobs( # pylint:disable=R0201
724 self, issue, patchset, reason, clobber, revision, masters): 727 self, issue, patchset, reason, clobber, revision, masters):
725 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' % 728 logging.info('ReadOnlyRietveld: triggering try jobs %r for issue %d' %
726 (masters, issue)) 729 (masters, issue))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698