Improve update computed field signaling so that we only emit signals when a host is added or deleted, or if it is associated or disassociated, or if a job runs

Conflicts:
	awx/main/signals.py
This commit is contained in:
Matthew Jones 2014-05-13 15:12:42 -04:00
parent db3151a9dd
commit 93c2a5e31c
3 changed files with 40 additions and 13 deletions

View File

@ -263,12 +263,13 @@ class Host(CommonModelNameNotUnique):
self.save(update_fields=computed_fields.keys())
# Groups and inventory may also need to be updated when host fields
# change.
if update_groups:
for group in self.all_groups.filter(active=True):
group.update_computed_fields()
if update_inventory:
self.inventory.update_computed_fields(update_groups=False,
update_hosts=False)
# NOTE: I think this is no longer needed
# if update_groups:
# for group in self.all_groups.filter(active=True):
# group.update_computed_fields()
# if update_inventory:
# self.inventory.update_computed_fields(update_groups=False,
# update_hosts=False)
# Rebuild summary fields cache
self.update_cached_values()
variables_dict = VarsDictProperty('variables')
@ -391,6 +392,7 @@ class Group(CommonModelNameNotUnique):
return reverse('api:group_detail', args=(self.pk,))
def mark_inactive_recursive(self, parent=None):
from awx.main.tasks import update_inventory_computed_fields
def mark_actual(parent=parent):
linked_children = [(parent, self)] + [(self, child) for child in self.children.all()]
marked_groups = []
@ -418,7 +420,7 @@ class Group(CommonModelNameNotUnique):
host.mark_inactive()
with ignore_inventory_computed_fields():
mark_actual()
self.inventory.update_computed_fields()
update_inventory_computed_fields.delay(self.id, True)
def mark_inactive(self, save=True, recompute=True):
'''

View File

@ -82,12 +82,31 @@ def emit_update_inventory_computed_fields(sender, **kwargs):
except Inventory.DoesNotExist:
pass
else:
update_inventory_computed_fields.delay(inventory.id, issubclass(sender, Job))
update_inventory_computed_fields.delay(inventory.id, True)
post_save.connect(emit_update_inventory_computed_fields, sender=Host)
post_delete.connect(emit_update_inventory_computed_fields, sender=Host)
post_save.connect(emit_update_inventory_computed_fields, sender=Group)
post_delete.connect(emit_update_inventory_computed_fields, sender=Group)
def emit_update_inventory_on_created_or_deleted(sender, **kwargs):
if getattr(_inventory_updates, 'is_updating', False):
return
instance = kwargs['instance']
if kwargs['created'] or not instance.active or kwargs['signal'] == post_delete:
pass
else:
return
sender_name = unicode(sender._meta.verbose_name)
logger.debug("%s created or deleted, updating inventory computed fields: %r %r",
sender_name, sender, kwargs)
try:
inventory = instance.inventory
except Inventory.DoesNotExist:
pass
else:
update_inventory_computed_fields.delay(inventory.id, True)
post_save.connect(emit_update_inventory_on_created_or_deleted, sender=Host)
post_delete.connect(emit_update_inventory_on_created_or_deleted, sender=Host)
post_save.connect(emit_update_inventory_on_created_or_deleted, sender=Group)
post_delete.connect(emit_update_inventory_on_created_or_deleted, sender=Group)
m2m_changed.connect(emit_update_inventory_computed_fields, sender=Group.hosts.through)
m2m_changed.connect(emit_update_inventory_computed_fields, sender=Group.parents.through)
m2m_changed.connect(emit_update_inventory_computed_fields, sender=Host.inventory_sources.through)

View File

@ -127,7 +127,7 @@ def handle_work_error(self, task_id, subtasks=None):
instance.socketio_emit_status("failed")
@task()
def update_inventory_computed_fields(inventory_id, should_update_hosts):
def update_inventory_computed_fields(inventory_id, should_update_hosts=True):
'''
Signal handler and wrapper around inventory.update_computed_fields to
prevent unnecessary recursive calls.
@ -589,6 +589,12 @@ class RunJob(BaseTask):
Hook for actions to run after job/task has completed.
'''
super(RunJob, self).post_run_hook(job, **kwargs)
try:
inventory = job.inventory
except Inventory.DoesNotExist:
pass
else:
update_inventory_computed_fields.delay(inventory.id, True)
# Update job event fields after job has completed (only when using REST
# API callback).
if not settings.CALLBACK_CONSUMER_PORT: