From cb4d55b47aa50451b9cab00356c42007cbb99ff8 Mon Sep 17 00:00:00 2001 From: chris meyers Date: Wed, 27 Mar 2019 16:35:16 -0400 Subject: [PATCH] fixes inventory update deadlock * all inventory updates continue to occur in parallel up to the point that they update the database with their results. * the "funnel" is achieved by using a global per-inventory postgres named lock --- .../management/commands/inventory_import.py | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/awx/main/management/commands/inventory_import.py b/awx/main/management/commands/inventory_import.py index ed6cf953e4..dd80d77140 100644 --- a/awx/main/management/commands/inventory_import.py +++ b/awx/main/management/commands/inventory_import.py @@ -41,6 +41,7 @@ from awx.main.utils import ( from awx.main.utils.common import _get_ansible_version from awx.main.signals import disable_activity_stream from awx.main.constants import STANDARD_INVENTORY_UPDATE_ENV +from awx.main.utils.pglock import advisory_lock logger = logging.getLogger('awx.main.commands.inventory_import') @@ -870,20 +871,21 @@ class Command(BaseCommand): Load inventory from in-memory groups to the database, overwriting or merging as appropriate. ''' - # FIXME: Attribute changes to superuser? - # Perform __in queries in batches (mainly for unit tests using SQLite). - self._batch_size = 500 - self._build_db_instance_id_map() - self._build_mem_instance_id_map() - if self.overwrite: - self._delete_hosts() - self._delete_groups() - self._delete_group_children_and_hosts() - self._update_inventory() - self._create_update_groups() - self._create_update_hosts() - self._create_update_group_children() - self._create_update_group_hosts() + with advisory_lock('inventory_{}_update'.format(self.inventory.id)): + # FIXME: Attribute changes to superuser? + # Perform __in queries in batches (mainly for unit tests using SQLite). + self._batch_size = 500 + self._build_db_instance_id_map() + self._build_mem_instance_id_map() + if self.overwrite: + self._delete_hosts() + self._delete_groups() + self._delete_group_children_and_hosts() + self._update_inventory() + self._create_update_groups() + self._create_update_hosts() + self._create_update_group_children() + self._create_update_group_hosts() def remote_tower_license_compare(self, local_license_type): # this requires https://github.com/ansible/ansible/pull/52747