From 32a3e48e244132e5d0a547342cacfe0bdcbc41f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 20 Oct 2022 13:14:01 +0200 Subject: [PATCH] Add-on: use job check endpoint before sending files to the farm --- addon/flamenco/job_submission.py | 13 +++++++ addon/flamenco/operators.py | 62 ++++++++++++++++++++++++++------ 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/addon/flamenco/job_submission.py b/addon/flamenco/job_submission.py index 8f66e195..dcb9ac4b 100644 --- a/addon/flamenco/job_submission.py +++ b/addon/flamenco/job_submission.py @@ -95,6 +95,19 @@ def submit_job(job: _SubmittedJob, api_client: _ApiClient) -> _Job: return response +def submit_job_check(job: _SubmittedJob, api_client: _ApiClient) -> None: + """Check the given job at Flamenco Manager to see if it is acceptable.""" + from flamenco.manager import ApiClient + from flamenco.manager.api import jobs_api + from flamenco.manager.models import SubmittedJob, Job + + assert isinstance(job, SubmittedJob), "got %s" % type(job) + assert isinstance(api_client, ApiClient), "got %s" % type(api_client) + + job_api_instance = jobs_api.JobsApi(api_client) + job_api_instance.submit_job_check(job) + + def is_file_inside_job_storage(context: bpy.types.Context, blendfile: Path) -> bool: """Check whether current blend file is inside the storage path. diff --git a/addon/flamenco/operators.py b/addon/flamenco/operators.py index d67585d8..acff3730 100644 --- a/addon/flamenco/operators.py +++ b/addon/flamenco/operators.py @@ -163,10 +163,8 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator): filepath = self._save_blendfile(context) - # Construct the Job locally before trying to pack. If any validations fail, better fail early. - self.job = job_submission.job_for_scene(context.scene) - if self.job is None: - self.report({"ERROR"}, "Unable to create job") + # Check the job with the Manager, to see if it would be accepted. + if not self._check_job(context): return {"CANCELLED"} return self._submit_files(context, filepath) @@ -427,14 +425,13 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator): self.blendfile_on_farm = bpathlib.make_absolute(blendfile) self._submit_job(context) - def _submit_job(self, context: bpy.types.Context) -> None: - """Use the Flamenco API to submit the new Job.""" - assert self.job is not None - assert self.blendfile_on_farm is not None + def _prepare_job_for_submission(self, context: bpy.types.Context) -> None: + """Prepare self.job for sending to Flamenco.""" - from flamenco.manager import ApiException - - api_client = self.get_api_client(context) + self.job = job_submission.job_for_scene(context.scene) + if self.job is None: + self.report({"ERROR"}, "Unable to create job") + return {"CANCELLED"} propgroup = getattr(context.scene, "flamenco_job_settings", None) assert isinstance(propgroup, JobTypePropertyGroup), "did not expect %s" % ( @@ -446,6 +443,16 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator): propgroup.job_type, self.job, self.blendfile_on_farm ) + def _submit_job(self, context: bpy.types.Context) -> None: + """Use the Flamenco API to submit the new Job.""" + assert self.job is not None + assert self.blendfile_on_farm is not None + + from flamenco.manager import ApiException + + self._prepare_job_for_submission(context) + + api_client = self.get_api_client(context) try: submitted_job = job_submission.submit_job(self.job, api_client) except MaxRetryError as ex: @@ -470,6 +477,39 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator): self.report({"INFO"}, "Job %s submitted" % submitted_job.name) + def _check_job(self, context: bpy.types.Context) -> bool: + """Use the Flamenco API to check the Job before submitting files. + + :return: "OK" flag, so True = ok, False = not ok. + """ + from flamenco.manager import ApiException + + self._prepare_job_for_submission(context) + + api_client = self.get_api_client(context) + try: + job_submission.submit_job_check(self.job, api_client) + except MaxRetryError as ex: + self.report({"ERROR"}, "Unable to reach Flamenco Manager") + return False + except HTTPError as ex: + self.report({"ERROR"}, "Error communicating with Flamenco Manager: %s" % ex) + return False + except ApiException as ex: + if ex.status == 412: + self.report( + {"ERROR"}, + "Cached job type is old. Refresh the job types and submit again, please", + ) + return False + if ex.status == 400: + error = parse_api_error(api_client, ex) + self.report({"ERROR"}, error.message) + return False + self.report({"ERROR"}, f"Could not check job: {ex.reason}") + return False + return True + def _quit(self, context: bpy.types.Context) -> set[str]: """Stop any timer and return a 'FINISHED' status.