mirror of
https://github.com/ansible/awx.git
synced 2026-04-12 13:39:24 -02:30
Sort both bulk updates and add batch size to facts bulk update to resolve deadlock issue Update tests to expect batch_size to agree with changes Add utility method to bulk update and sort hosts and applied that to the appropriate locations Update functional tests to use bulk_update_sorted_by_id since update_hosts has been deleted Add comment NOSONAR to get rid of Sonarqube warning since this is just a test and it's not actually a security issue Fix failing test test_finish_job_fact_cache_clear & test_finish_job_fact_cache_with_existing_data --------- Signed-off-by: Seth Foster <fosterbseth@gmail.com> Co-authored-by: Alan Rominger <arominge@redhat.com> Co-authored-by: Seth Foster <fosterbseth@gmail.com>
35 lines
1.3 KiB
Python
35 lines
1.3 KiB
Python
# Copyright (c) 2017 Ansible by Red Hat
|
|
# All Rights Reserved.
|
|
|
|
from awx.settings.application_name import set_application_name
|
|
|
|
from django.conf import settings
|
|
|
|
|
|
def set_connection_name(function):
|
|
set_application_name(settings.DATABASES, settings.CLUSTER_HOST_ID, function=function)
|
|
|
|
|
|
def bulk_update_sorted_by_id(model, objects, fields, batch_size=1000):
|
|
"""
|
|
Perform a sorted bulk update on model instances to avoid database deadlocks.
|
|
|
|
This function was introduced to prevent deadlocks observed in the AWX Controller
|
|
when concurrent jobs attempt to update different fields on the same `main_hosts` table.
|
|
Specifically, deadlocks occurred when one process updated `last_job_id` while another
|
|
simultaneously updated `ansible_facts`.
|
|
|
|
By sorting updates ID, we ensure a consistent update order,
|
|
which helps avoid the row-level locking contention that can lead to deadlocks
|
|
in PostgreSQL when multiple processes are involved.
|
|
|
|
Returns:
|
|
int: The number of rows affected by the update.
|
|
"""
|
|
objects = [obj for obj in objects if obj.id is not None]
|
|
if not objects:
|
|
return 0 # Return 0 when nothing is updated
|
|
|
|
sorted_objects = sorted(objects, key=lambda obj: obj.id)
|
|
return model.objects.bulk_update(sorted_objects, fields, batch_size=batch_size)
|