|
4 | 4 | import tempfile
|
5 | 5 | import tarfile
|
6 | 6 | import zipfile
|
| 7 | +from functools import wraps |
7 | 8 |
|
8 | 9 | import gitlab
|
9 | 10 |
|
10 | 11 |
|
11 | 12 | class Gitlab(object):
|
12 | 13 | JOB_NAME_PATTERN = re.compile(r"(\w+)(\s+(\d+)/(\d+))?")
|
13 | 14 |
|
| 15 | + DOWNLOAD_ERROR_MAX_RETRIES = 3 |
| 16 | + |
14 | 17 | def __init__(self, project_id=None):
|
15 | 18 | config_data_from_env = os.getenv("PYTHON_GITLAB_CONFIG")
|
16 | 19 | if config_data_from_env:
|
@@ -64,6 +67,31 @@ def download_artifacts(self, job_id, destination):
|
64 | 67 | with zipfile.ZipFile(temp_file.name, "r") as archive_file:
|
65 | 68 | archive_file.extractall(destination)
|
66 | 69 |
|
| 70 | + def retry_download(func): |
| 71 | + """ |
| 72 | + This wrapper will only catch IOError and retry the whole function. |
| 73 | +
|
| 74 | + So only use it with download functions, read() inside and atomic |
| 75 | + functions |
| 76 | + """ |
| 77 | + @wraps(func) |
| 78 | + def wrapper(self, *args, **kwargs): |
| 79 | + retried = 0 |
| 80 | + while True: |
| 81 | + try: |
| 82 | + res = func(self, *args, **kwargs) |
| 83 | + except (IOError, EOFError) as e: |
| 84 | + retried += 1 |
| 85 | + if retried > self.DOWNLOAD_ERROR_MAX_RETRIES: |
| 86 | + raise e # get out of the loop |
| 87 | + else: |
| 88 | + print('Retried for the {} time'.format(retried)) |
| 89 | + continue |
| 90 | + else: |
| 91 | + break |
| 92 | + return res |
| 93 | + return wrapper |
| 94 | + |
67 | 95 | def download_artifact(self, job_id, artifact_path, destination=None):
|
68 | 96 | """
|
69 | 97 | download specific path of job artifacts and extract to destination.
|
@@ -118,6 +146,7 @@ def find_job_id(self, job_name, pipeline_id=None, job_status="success"):
|
118 | 146 | job_id_list.append({"id": job.id, "parallel_num": match.group(3)})
|
119 | 147 | return job_id_list
|
120 | 148 |
|
| 149 | + @retry_download |
121 | 150 | def download_archive(self, ref, destination, project_id=None):
|
122 | 151 | """
|
123 | 152 | Download archive of certain commit of a repository and extract to destination path
|
|
0 commit comments