aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/PCbuild/get_external.py
diff options
context:
space:
mode:
Diffstat (limited to 'PCbuild/get_external.py')
-rwxr-xr-xPCbuild/get_external.py26
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