New patch against hostvars.py. With this patch, Ansible run lose 50% of time.

Little rewrite of previous patch to use sha1 signature.
Use fail_on_undefined to compute sha1 signature.
pull/13000/head
Yannig Perré 9 years ago
parent 805f768dab
commit 4a8d1703d4

@ -39,6 +39,11 @@ from ansible.template.template import AnsibleJ2Template
from ansible.template.vars import AnsibleJ2Vars from ansible.template.vars import AnsibleJ2Vars
from ansible.utils.debug import debug from ansible.utils.debug import debug
try:
from hashlib import sha1
except ImportError:
from sha import sha as sha1
from numbers import Number from numbers import Number
__all__ = ['Templar'] __all__ = ['Templar']
@ -270,6 +275,9 @@ class Templar:
before being sent through the template engine. before being sent through the template engine.
''' '''
if fail_on_undefined is None:
fail_on_undefined = self._fail_on_undefined_errors
# Don't template unsafe variables, instead drop them back down to # Don't template unsafe variables, instead drop them back down to
# their constituent type. # their constituent type.
if hasattr(variable, '__UNSAFE__'): if hasattr(variable, '__UNSAFE__'):
@ -302,10 +310,10 @@ class Templar:
return C.DEFAULT_NULL_REPRESENTATION return C.DEFAULT_NULL_REPRESENTATION
# Using a cache in order to prevent template calls with already templated variables # Using a cache in order to prevent template calls with already templated variables
cache_key = variable + str(preserve_trailing_newlines) + str(escape_backslashes) + str(overrides) sha1_hash = sha1(variable + str(preserve_trailing_newlines) + str(escape_backslashes) + str(fail_on_undefined) + str(overrides)).hexdigest()
try: if sha1_hash in self._cached_result:
result = self._cached_result[cache_key] result = self._cached_result[sha1_hash]
except KeyError: else:
result = self._do_template(variable, preserve_trailing_newlines=preserve_trailing_newlines, escape_backslashes=escape_backslashes, fail_on_undefined=fail_on_undefined, overrides=overrides) result = self._do_template(variable, preserve_trailing_newlines=preserve_trailing_newlines, escape_backslashes=escape_backslashes, fail_on_undefined=fail_on_undefined, overrides=overrides)
if convert_data: if convert_data:
# if this looks like a dictionary or list, convert it to such using the safe_eval method # if this looks like a dictionary or list, convert it to such using the safe_eval method
@ -317,7 +325,7 @@ class Templar:
else: else:
# FIXME: if the safe_eval raised an error, should we do something with it? # FIXME: if the safe_eval raised an error, should we do something with it?
pass pass
self._cached_result[cache_key] = result self._cached_result[sha1_hash] = result
#return self._clean_data(result) #return self._clean_data(result)

@ -28,6 +28,11 @@ from ansible import constants as C
from ansible.inventory.host import Host from ansible.inventory.host import Host
from ansible.template import Templar from ansible.template import Templar
try:
from hashlib import sha1
except ImportError:
from sha import sha as sha1
__all__ = ['HostVars'] __all__ = ['HostVars']
# Note -- this is a Mapping, not a MutableMapping # Note -- this is a Mapping, not a MutableMapping
@ -39,6 +44,7 @@ class HostVars(collections.Mapping):
self._loader = loader self._loader = loader
self._play = play self._play = play
self._variable_manager = variable_manager self._variable_manager = variable_manager
self._cached_result = {}
hosts = inventory.get_hosts(ignore_limits_and_restrictions=True) hosts = inventory.get_hosts(ignore_limits_and_restrictions=True)
@ -68,8 +74,16 @@ class HostVars(collections.Mapping):
host = self._lookup.get(host_name) host = self._lookup.get(host_name)
data = self._variable_manager.get_vars(loader=self._loader, host=host, play=self._play, include_hostvars=False) data = self._variable_manager.get_vars(loader=self._loader, host=host, play=self._play, include_hostvars=False)
templar = Templar(variables=data, loader=self._loader)
return templar.template(data, fail_on_undefined=False) # Using cache in order to avoid template call
sha1_hash = sha1(str(data)).hexdigest()
if sha1_hash in self._cached_result:
result = self._cached_result[sha1_hash]
else:
templar = Templar(variables=data, loader=self._loader)
result = templar.template(data, fail_on_undefined=False)
self._cached_result[sha1_hash] = result
return result
def __contains__(self, host_name): def __contains__(self, host_name):
item = self.get(host_name) item = self.get(host_name)

Loading…
Cancel
Save