Skip to content

Commit

Permalink
Register handlers immediately if currently iterating handlers
Browse files Browse the repository at this point in the history
This fixes the issue where handlers notifying other handlers are
not properly run because the notification is not registered unless
another flush_handlers occurs. Instead, if the current host state
is iterating handlers we immediately register the handler to be
run so the notification is not lost.

Fixes ansible#80880
  • Loading branch information
jimi-c committed May 26, 2023
1 parent e88ff32 commit d129943
Showing 1 changed file with 20 additions and 12 deletions.
32 changes: 20 additions & 12 deletions lib/ansible/plugins/strategy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -653,19 +653,27 @@ def _process_pending_results(self, iterator, one_pass=False, max_passes=None):
# handlers are actually flushed so the last defined handlers are exexcuted,
# otherwise depending on the setting either error or warn
for notification in result_item['_ansible_notify']:
if any(self.search_handlers_by_notification(notification, iterator)):
iterator.add_notification(original_host.name, notification)
display.vv(f"Notification for handler {notification} has been saved.")
continue

msg = (
f"The requested handler '{notification}' was not found in either the main handlers"
" list nor in the listening handlers list"
)
if C.ERROR_ON_MISSING_HANDLER:
raise AnsibleError(msg)
for handler in self.search_handlers_by_notification(notification, iterator):
host_state = iterator.get_state_for_host(original_host.name)
if host_state.run_state == IteratingStates.HANDLERS:
# we're currently iterating handlers, so we need to expand this now
if handler.notify_host(original_host):
# NOTE even with notifications deduplicated this can still happen in case of handlers being
# notified multiple times using different names, like role name or fqcn
self._tqm.send_callback('v2_playbook_on_notify', handler, original_host.name)
else:
iterator.add_notification(original_host.name, notification)
display.vv(f"Notification for handler {notification} has been saved.")
break
else:
display.warning(msg)
msg = (
f"The requested handler '{notification}' was not found in either the main handlers"
" list nor in the listening handlers list"
)
if C.ERROR_ON_MISSING_HANDLER:
raise AnsibleError(msg)
else:
display.warning(msg)

if 'add_host' in result_item:
# this task added a new host (add_host module)
Expand Down

0 comments on commit d129943

Please sign in to comment.