From e38f74159d876be0d8400b2385bf7ad353f39893 Mon Sep 17 00:00:00 2001 From: Martin Krizek Date: Tue, 12 Nov 2019 19:48:07 +0100 Subject: [PATCH] 2.9: perf: reduce getting handler variables (#59969) (#64676) * perf: reduce getting handler variables (#59969) * perf: reduce getting handler variables ci_complete * Do not re-create templar (cherry picked from commit 9ccef9e8192084e9e6b38c36a38c820fc8bd66db) * Add changelog --- .../59017-perf-regression-handlers.yml | 2 ++ lib/ansible/plugins/strategy/__init__.py | 21 ++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 changelogs/fragments/59017-perf-regression-handlers.yml diff --git a/changelogs/fragments/59017-perf-regression-handlers.yml b/changelogs/fragments/59017-perf-regression-handlers.yml new file mode 100644 index 0000000000..cb61b9294d --- /dev/null +++ b/changelogs/fragments/59017-perf-regression-handlers.yml @@ -0,0 +1,2 @@ +bugfixes: + - Fix for performance regression in handler invocation (https://github.com/ansible/ansible/issues/59017) diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py index 09a1e0355f..5f6974cea0 100644 --- a/lib/ansible/plugins/strategy/__init__.py +++ b/lib/ansible/plugins/strategy/__init__.py @@ -385,12 +385,6 @@ class StrategyBase: host_name = result.get('_ansible_delegated_vars', {}).get('ansible_delegated_host', None) return [host_name or task.delegate_to] - def get_handler_templar(self, handler_task, iterator): - handler_vars = self._variable_manager.get_vars(play=iterator._play, task=handler_task, - _hosts=self._hosts_cache, - _hosts_all=self._hosts_cache_all) - return Templar(loader=self._loader, variables=handler_vars) - @debug_closure def _process_pending_results(self, iterator, one_pass=False, max_passes=None): ''' @@ -399,6 +393,7 @@ class StrategyBase: ''' ret_results = [] + handler_templar = Templar(self._loader) def get_original_host(host_name): # FIXME: this should not need x2 _inventory @@ -414,8 +409,12 @@ class StrategyBase: for handler_task in handler_block.block: if handler_task.name: if not handler_task.cached_name: - templar = self.get_handler_templar(handler_task, iterator) - handler_task.name = templar.template(handler_task.name) + if handler_templar.is_template(handler_task.name): + handler_templar.available_variables = self._variable_manager.get_vars(play=iterator._play, + task=handler_task, + _hosts=self._hosts_cache, + _hosts_all=self._hosts_cache_all) + handler_task.name = handler_templar.template(handler_task.name) handler_task.cached_name = True try: @@ -570,9 +569,11 @@ class StrategyBase: for listening_handler_block in iterator._play.handlers: for listening_handler in listening_handler_block.block: listeners = getattr(listening_handler, 'listen', []) or [] - templar = self.get_handler_templar(listening_handler, iterator) + if not listeners: + continue + listeners = listening_handler.get_validated_value( - 'listen', listening_handler._valid_attrs['listen'], listeners, templar + 'listen', listening_handler._valid_attrs['listen'], listeners, handler_templar ) if handler_name not in listeners: continue