Skip to content

Commit 3126ef0

Browse files
committedMay 18, 2018
Retry HTTP requests after HTTP errors
Retry HTTP requests if we get a HTTP 500 from the server when collecting data. It is a temporary condition that has been encountered with hg.mozilla.org and can crash the program on long runs.
1 parent 0f4d87f commit 3126ef0

File tree

5 files changed

+59
-9
lines changed

5 files changed

+59
-9
lines changed
 

‎committelemetry/classifier.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from mozautomation.commitparser import parse_bugs
1414

1515
from committelemetry import config
16+
from committelemetry.http import requests_retry_session
1617

1718
log = logging.getLogger(__name__)
1819

@@ -58,7 +59,7 @@ def fetch_attachments(bug_id):
5859
"""Fetch the given bug's attachment list from Bugzilla."""
5960
# Example: https://bugzilla.mozilla.org/rest/bug/1447193/attachment?exclude_fields=data
6061
url = f'{config.BMO_API_URL}/bug/{bug_id}/attachment?exclude_fields=data'
61-
response = requests.get(url)
62+
response = requests_retry_session().get(url)
6263

6364
# TODO Workaround for bug 1462349. Can be removed when API calls return the correct value.
6465
if 'error' in response.json():
@@ -73,7 +74,7 @@ def fetch_bug_history(bug_id):
7374
"""Fetch the given bug's history from Bugzilla."""
7475
# Example: https://bugzilla.mozilla.org/rest/bug/1447193/history
7576
url = f'{config.BMO_API_URL}/bug/{bug_id}/history'
76-
response = requests.get(url)
77+
response = requests_retry_session().get(url)
7778

7879
# TODO Workaround for bug 1462349. Can be removed when API calls return the correct value.
7980
if 'error' in response.json():

‎committelemetry/http.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# This Source Code Form is subject to the terms of the Mozilla Public
2+
# License, v. 2.0. If a copy of the MPL was not distributed with this
3+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
"""
5+
Functions related to basic network communication tasks.
6+
"""
7+
import requests
8+
from requests.adapters import HTTPAdapter
9+
from urllib3 import Retry
10+
11+
12+
def requests_retry_session(
13+
retries=3,
14+
backoff_factor=0.3,
15+
status_forcelist=(500, 502, 504),
16+
session=None
17+
):
18+
"""Return a python-requests Session that retries on HTTP failure.
19+
20+
For usage see
21+
https://www.peterbe.com/plog/best-practice-with-retries-with-requests.
22+
23+
Args:
24+
retries: optional int, number of retries to attempt.
25+
backoff_factor: See https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html#module-urllib3.util.retry.
26+
status_forcelist: optional list of HTTP status codes that will trigger
27+
a retry.
28+
session: optional pre-built requests.Session object.
29+
30+
Returns:
31+
A requests.Session object we can use to call .get(), post() etc.
32+
"""
33+
session = session or requests.Session()
34+
retry = Retry(
35+
total=retries,
36+
read=retries,
37+
connect=retries,
38+
backoff_factor=backoff_factor,
39+
status_forcelist=status_forcelist,
40+
)
41+
adapter = HTTPAdapter(max_retries=retry)
42+
session.mount('http://', adapter)
43+
session.mount('https://', adapter)
44+
return session

‎committelemetry/pulse.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
from contextlib import closing
1111
from functools import partial
1212

13-
import requests
1413
from kombu import Connection, Exchange, Queue
1514

1615
from committelemetry import config
16+
from committelemetry.http import requests_retry_session
1717
from committelemetry.telemetry import payload_for_changeset, send_ping
1818

1919
log = logging.getLogger(__name__)
@@ -41,7 +41,7 @@ def changesets_for_pushid(pushid, push_json_url):
4141
A list of changeset ID strings (40 char hex strings).
4242
"""
4343
log.info(f'processing pushid {pushid}')
44-
response = requests.get(push_json_url)
44+
response = requests_retry_session().get(push_json_url)
4545
response.raise_for_status()
4646

4747
# See https://mozilla-version-control-tools.readthedocs.io/en/latest/hgmo/pushlog.html#version-2

‎committelemetry/pushlog.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
"""
99
import logging
1010

11-
import requests
12-
11+
from committelemetry.http import requests_retry_session
1312
from committelemetry.telemetry import payload_for_changeset, send_ping
1413

1514
log = logging.getLogger(__name__)
@@ -30,7 +29,9 @@ def pushes_for_range(repo_url, starting_push_id, ending_push_id):
3029
"""
3130
# See https://mozilla-version-control-tools.readthedocs.io/en/latest/hgmo/pushlog.html#version-2
3231
params = dict(startID=starting_push_id, endID=ending_push_id, version=2)
33-
response = requests.get(f'{repo_url}/json-pushes/', params=params)
32+
response = requests_retry_session().get(
33+
f'{repo_url}/json-pushes/', params=params
34+
)
3435
response.raise_for_status()
3536
pushlog = response.json()
3637
return pushlog['pushes']
@@ -49,7 +50,9 @@ def send_pings_by_pushid(repo_url, starting_push_id, ending_push_id, no_send):
4950
if no_send:
5051
log.info('transmission of ping data has been disabled')
5152

52-
for pushid, pushdata in pushes_for_range(repo_url, starting_push_id, ending_push_id).items():
53+
for pushid, pushdata in pushes_for_range(
54+
repo_url, starting_push_id, ending_push_id
55+
).items():
5356
log.info(f'processing pushid {pushid}')
5457

5558
# See https://mozilla-version-control-tools.readthedocs.io/en/latest/hgmo/pushlog.html#version-2

‎committelemetry/telemetry.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
from committelemetry import config
1313
from committelemetry.classifier import determine_review_system
14+
from committelemetry.http import requests_retry_session
1415

1516
log = logging.getLogger(__name__)
1617

@@ -33,7 +34,8 @@ def payload_for_changeset(changesetid, repo_url):
3334
mercurial repository.
3435
"""
3536
# Example URL: https://hg.mozilla.org/mozilla-central/json-rev/deafa2891c61
36-
response = requests.get(f'{repo_url}/json-rev/{changesetid}')
37+
response = requests_retry_session(
38+
).get(f'{repo_url}/json-rev/{changesetid}')
3739

3840
if response.status_code == 404:
3941
raise NoSuchChangeset(

0 commit comments

Comments
 (0)
Failed to load comments.