Skip to content

Commit

Permalink
Avoid default serialization of classes in dump_attrs
Browse files Browse the repository at this point in the history
For playbook base objects, when dumping attributes via dump_attrs() an
attribute like loop_control is a class. Using the default serialization
for these is slow and consumes a lot of memory. Since LoopControl is also
based on the Base class, we can use serialize() instead and save a lot of
resources.

This also adds a from_attrs() complimentary method to nicely turn the
dumped attrs back into proper field attributes.

Fixes ansible#23579
  • Loading branch information
jimi-c committed May 11, 2017
1 parent 409fe1a commit 78478e8
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
22 changes: 20 additions & 2 deletions lib/ansible/playbook/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,10 +506,28 @@ def dump_attrs(self):
Dumps all attributes to a dictionary
'''
attrs = dict()
for name in self._valid_attrs.keys():
attrs[name] = getattr(self, name)
for (name, attribute) in iteritems(self._valid_attrs):
attr = getattr(self, name)
if attribute.isa == 'class' and attr is not None and hasattr(attr, 'serialize'):
attrs[name] = attr.serialize()
else:
attrs[name] = attr
return attrs

def from_attrs(self, attrs):
'''
Loads attributes from a dictionary
'''
for (attr, value) in iteritems(attrs):
if attr in self._valid_attrs:
attribute = self._valid_attrs[attr]
if attribute.isa == 'class' and isinstance(value, dict):
obj = attribute.class_type()
obj.deserialize(value)
setattr(self, attr, obj)
else:
setattr(self, attr, value)

def serialize(self):
'''
Serializes the object derived from the base object into
Expand Down
3 changes: 1 addition & 2 deletions lib/ansible/plugins/strategy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,7 @@ def parent_handler_match(target_handler, handler_name):
found_task = iterator.get_original_task(original_host, task_result._task)
original_task = found_task.copy(exclude_parent=True, exclude_tasks=True)
original_task._parent = found_task._parent
for (attr, val) in iteritems(task_result._task_fields):
setattr(original_task, attr, val)
original_task.from_attrs(task_result._task_fields)

task_result._host = original_host
task_result._task = original_task
Expand Down

0 comments on commit 78478e8

Please sign in to comment.