From 1a205af41f84fce21e6170f17aa3235defae806c Mon Sep 17 00:00:00 2001 From: Dirk Julich Date: Fri, 20 Mar 2026 21:03:12 +0100 Subject: [PATCH] AAP-57614 fix: remove early dispatch, rely on events_processed_hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dispatching save_indirect_host_entries from artifacts_handler was fundamentally flawed: it ran before job events were written to the DB by the callback receiver, so the task found no events to process, set event_queries_processed=True, and blocked all future processing. Remove the dispatch and the now-unused import. The existing events_processed_hook (called from both the task runner after the final save and the callback receiver after the wrapup event) handles dispatching at the right time — after events are in the DB. The direct DB write of event_queries_processed=False and installed_collections (added in the previous commit) remains: it ensures events_processed_hook sees the correct values regardless of which call site runs first. Co-Authored-By: Claude Opus 4.6 --- awx/main/tasks/callback.py | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/awx/main/tasks/callback.py b/awx/main/tasks/callback.py index 48a4d10e5c..16c63fe34d 100644 --- a/awx/main/tasks/callback.py +++ b/awx/main/tasks/callback.py @@ -6,7 +6,6 @@ from collections import deque from typing import Tuple, Optional from awx.main.models.event_query import EventQuery -from awx.main.tasks.host_indirect import save_indirect_host_entries # Django from django.conf import settings @@ -302,12 +301,16 @@ class RunnerCallback: logger.warning(f'The file {COLLECTION_FILENAME} unexpectedly did not contain ansible_version') # Write event_queries_processed and installed_collections directly - # to the DB rather than using delay_update alone. delay_update - # only writes when the final job status is saved, but - # save_indirect_host_entries needs both values in the DB - # immediately: event_queries_processed=False to pass the - # select_for_update gate, and installed_collections to find - # matching EventQuery records via fetch_job_event_query. + # to the DB instead of using delay_update. delay_update defers + # writes until the final job status save, but + # events_processed_hook (called from both the task runner after + # the final save and the callback receiver after the wrapup + # event) needs event_queries_processed=False visible in the DB + # to dispatch save_indirect_host_entries. The field defaults to + # True, so without a direct write the hook would see True and + # skip the dispatch. installed_collections is also written + # directly so it is available if the callback receiver + # dispatches before the final save. from awx.main.models import Job db_updates = {'event_queries_processed': False} @@ -315,14 +318,6 @@ class RunnerCallback: db_updates['installed_collections'] = query_file_contents['installed_collections'] Job.objects.filter(id=self.instance.id).update(**db_updates) - # Dispatch save_indirect_host_entries to process the EventQuery - # records created above. handle_success_and_failure_notifications - # may have already run and skipped dispatching because - # event_queries_processed defaults to True and artifacts_handler - # can run after the notification handler. The task's - # select_for_update lock prevents duplicate processing. - save_indirect_host_entries.delay(self.instance.id) - self.artifacts_processed = True