|
8 | 8 | import click
|
9 | 9 | from dynaconf import Validator
|
10 | 10 | from logzero import logger
|
| 11 | +from requests.exceptions import ConnectionError |
11 | 12 |
|
12 | 13 | from broker import exceptions
|
13 | 14 | from broker.helpers import eval_filter, find_origin, yaml
|
@@ -41,6 +42,19 @@ def convert_pseudonamespaces(attr_dict):
|
41 | 42 | return out_dict
|
42 | 43 |
|
43 | 44 |
|
| 45 | +def resilient_job_wait(job, timeout=None): |
| 46 | + """Wait for a job to complete. Retry on errors.""" |
| 47 | + timeout = timeout or settings.ANSIBLETOWER.workflow_timeout |
| 48 | + completed = False |
| 49 | + while not completed: |
| 50 | + try: |
| 51 | + job.wait_until_completed(timeout=timeout) |
| 52 | + completed = True |
| 53 | + except ConnectionError as err: |
| 54 | + logger.error(f"Error occurred while waiting for job: {err}") |
| 55 | + logger.info("Retrying job wait...") |
| 56 | + |
| 57 | + |
44 | 58 | class JobExecutionError(exceptions.ProviderError):
|
45 | 59 | """Raised when a job execution fails."""
|
46 | 60 |
|
@@ -605,7 +619,7 @@ def execute(self, **kwargs): # noqa: PLR0912,PLR0915 - Possible TODO refactor
|
605 | 619 | job_ui_url = url_parser.urljoin(self.url, f"/#/{subject}s/{job_number}")
|
606 | 620 | helpers.emit(api_url=job_api_url, ui_url=job_ui_url)
|
607 | 621 | logger.info(f"Waiting for job: \nAPI: {job_api_url}\nUI: {job_ui_url}")
|
608 |
| - job.wait_until_completed(timeout=settings.ANSIBLETOWER.workflow_timeout) |
| 622 | + resilient_job_wait(job) |
609 | 623 | if job.status != "successful":
|
610 | 624 | message_data = {
|
611 | 625 | f"{subject.capitalize()} Status": job.status,
|
|
0 commit comments