Lazy-load plugin registries, move DB sync to dispatcher (#16483)

Move plugin loading to lazy-on-first-access, DB sync to dispatcher

Remove credential type and inventory plugin loading from Django's
app.ready() path. In-memory registries (ManagedCredentialType.registry
and InventorySourceOptions.injectors) are now populated lazily on first
access via LazyLoadDict, a dict subclass that calls a loader function
on the first read operation. This ensures web workers, dispatcher
workers, and management commands all get the registries populated
exactly when needed, without eager loading at startup.

The DB sync (CredentialType.setup_tower_managed_defaults) is moved to
the dispatcher's startup task, where it only needs to run once per
deployment rather than in every Django process.

Co-Authored-By: Alan Rominger <arominge@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Seth Foster
2026-06-09 12:45:50 -04:00
committed by GitHub
parent d566f71ae0
commit d5e5ea3670
9 changed files with 115 additions and 69 deletions

View File

@@ -1,7 +1,8 @@
import pytest
# AWX context managers for testing
from awx.main.signals import disable_activity_stream, disable_computed_fields, update_inventory_computed_fields
from awx.main.signals import disable_activity_stream, disable_computed_fields
from awx.main.tasks.system import update_inventory_computed_fields
# AWX models
from awx.main.models.organization import Organization

View File

@@ -3,6 +3,8 @@ import pytest
from django.apps import apps
from django.core.management.base import CommandError
from awx.main.tasks.system import _sync_credential_types_to_db
@pytest.fixture
def mock_setup_tower_managed_defaults(mocker):
@@ -10,19 +12,19 @@ def mock_setup_tower_managed_defaults(mocker):
@pytest.mark.django_db
def test_load_credential_types_feature_migrations_ran(mocker, mock_setup_tower_managed_defaults):
mocker.patch('awx.main.apps.is_database_synchronized', return_value=True)
def test_sync_credential_types_migrations_ran(mocker, mock_setup_tower_managed_defaults):
mocker.patch('awx.main.tasks.system.is_database_synchronized', return_value=True)
apps.get_app_config('main')._load_credential_types_feature()
_sync_credential_types_to_db()
mock_setup_tower_managed_defaults.assert_called_once()
@pytest.mark.django_db
def test_load_credential_types_feature_migrations_not_ran(mocker, mock_setup_tower_managed_defaults):
mocker.patch('awx.main.apps.is_database_synchronized', return_value=False)
def test_sync_credential_types_migrations_not_ran(mocker, mock_setup_tower_managed_defaults):
mocker.patch('awx.main.tasks.system.is_database_synchronized', return_value=False)
apps.get_app_config('main')._load_credential_types_feature()
_sync_credential_types_to_db()
mock_setup_tower_managed_defaults.assert_not_called()