diff --git a/awx/main/tasks/callback.py b/awx/main/tasks/callback.py index f92a6028d22e..3c5d4b23b970 100644 --- a/awx/main/tasks/callback.py +++ b/awx/main/tasks/callback.py @@ -203,12 +203,12 @@ def status_handler(self, status_data, runner_config): if os.path.exists(key_data_file) and stat.S_ISFIFO(os.stat(key_data_file).st_mode): os.remove(key_data_file) elif status_data['status'] == 'error': - result_traceback = status_data.get('result_traceback', None) - if result_traceback: - from awx.main.signals import disable_activity_stream # Circular import - - with disable_activity_stream(): - self.instance = self.update_model(self.instance.pk, result_traceback=result_traceback) + updates = {} + for potential_field in ('result_traceback', 'job_explanation'): + if status_data.get(potential_field, None): + updates[potential_field] = status_data[potential_field] + if updates: + self.instance = self.update_model(self.instance.pk, **updates) class RunnerCallbackForProjectUpdate(RunnerCallback): diff --git a/awx/main/tasks/jobs.py b/awx/main/tasks/jobs.py index f09fc7e7398d..9e9692ff10fc 100644 --- a/awx/main/tasks/jobs.py +++ b/awx/main/tasks/jobs.py @@ -546,6 +546,11 @@ def run(self, pk, **kwargs): status = res.status rc = res.rc + # We call this to get the current values from the database, in case update_model was called + # within the threadpools inside of AWXReceptorJob. We use update_model instead of + # refresh_from_db here because it contains retry logic that is resilient to database failures. + self.instance = self.update_model(self.instance.pk) + if status in ('timeout', 'error'): job_explanation = f"Job terminated due to {status}" self.instance.job_explanation = self.instance.job_explanation or job_explanation @@ -580,7 +585,6 @@ def run(self, pk, **kwargs): if 'got an unexpected keyword argument' in extra_update_fields.get('result_traceback', ''): extra_update_fields['result_traceback'] = "{}\n\n{}".format(extra_update_fields['result_traceback'], ANSIBLE_RUNNER_NEEDS_UPDATE_MESSAGE) - self.instance = self.update_model(pk) self.instance = self.update_model(pk, status=status, emitted_events=self.runner_callback.event_ct, **extra_update_fields) try: