diff options
Diffstat (limited to 'PCbuild/get_external.py')
-rwxr-xr-x | PCbuild/get_external.py | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/PCbuild/get_external.py b/PCbuild/get_external.py index 4ecc8925349..a78aa6a2304 100755 --- a/PCbuild/get_external.py +++ b/PCbuild/get_external.py @@ -5,8 +5,28 @@ import os import pathlib import sys import time +import urllib.error +import urllib.request import zipfile -from urllib.request import urlretrieve + + +def retrieve_with_retries(download_location, output_path, reporthook, + max_retries=7): + """Download a file with exponential backoff retry and save to disk.""" + for attempt in range(max_retries + 1): + try: + resp = urllib.request.urlretrieve( + download_location, + output_path, + reporthook=reporthook, + ) + except (urllib.error.URLError, ConnectionError) as ex: + if attempt == max_retries: + msg = f"Download from {download_location} failed." + raise OSError(msg) from ex + time.sleep(2.25**attempt) + else: + return resp def fetch_zip(commit_hash, zip_dir, *, org='python', binary=False, verbose): @@ -16,10 +36,10 @@ def fetch_zip(commit_hash, zip_dir, *, org='python', binary=False, verbose): if verbose: reporthook = print zip_dir.mkdir(parents=True, exist_ok=True) - filename, headers = urlretrieve( + filename, _headers = retrieve_with_retries( url, zip_dir / f'{commit_hash}.zip', - reporthook=reporthook, + reporthook ) return filename |