diff --git a/CHANGES/+collection_delete_memory.bugfix b/CHANGES/+collection_delete_memory.bugfix new file mode 100644 index 000000000..18b6d4cc0 --- /dev/null +++ b/CHANGES/+collection_delete_memory.bugfix @@ -0,0 +1 @@ +Reduced memory usage when deleting collections with many versions by using targeted QuerySet field selection with `.only()` to avoid loading unnecessary JSON fields. diff --git a/pulp_ansible/app/galaxy/v3/views.py b/pulp_ansible/app/galaxy/v3/views.py index 1f1c1fb4d..4fa883580 100644 --- a/pulp_ansible/app/galaxy/v3/views.py +++ b/pulp_ansible/app/galaxy/v3/views.py @@ -57,6 +57,7 @@ AnsibleCollectionDeprecated, AnsibleDistribution, AnsibleNamespaceMetadata, + AnsibleRepository, Collection, CollectionDownloadCount, CollectionVersion, @@ -447,9 +448,9 @@ def destroy(self, request: Request, *args, **kwargs) -> Response: ) repositories = set() - for version in collection.versions.all(): - for repo in version.repositories.all(): - repositories.add(repo) + for version in collection.versions.only("pk"): + repositories.update(version.repositories.only("pk")) + repositories = AnsibleRepository.objects.filter(pk__in=repositories) async_result = dispatch( delete_collection, @@ -464,9 +465,9 @@ def get_collection_dependents(parent): """Given a parent collection, return a list of collection versions that depend on it.""" key = f"{parent.namespace}.{parent.name}" return list( - CollectionVersion.objects.exclude(collection=parent).filter( - dependencies__has_key=key, pulp_domain=get_domain() - ) + CollectionVersion.objects.exclude(collection=parent) + .filter(dependencies__has_key=key, pulp_domain=get_domain()) + .only("namespace", "name", "version") ) diff --git a/pulp_ansible/app/tasks/deletion.py b/pulp_ansible/app/tasks/deletion.py index c664dbc1e..8b3825181 100644 --- a/pulp_ansible/app/tasks/deletion.py +++ b/pulp_ansible/app/tasks/deletion.py @@ -32,7 +32,7 @@ def _remove_collection_version_from_repos(collection_versions): """Remove CollectionVersions from latest RepositoryVersion of each repo.""" repos_with_collections_to_delete = defaultdict(list) for collection_version in collection_versions: - for repo in collection_version.repositories.all(): + for repo in collection_version.repositories.only("pk"): repos_with_collections_to_delete[repo].append(collection_version.pk) for repo, collections in repos_with_collections_to_delete.items(): add_and_remove(repo.pk, add_content_units=[], remove_content_units=collections) @@ -72,7 +72,7 @@ def delete_collection(collection_pk): 3. Delete Collection """ collection = Collection.objects.get(pk=collection_pk) - versions = collection.versions.all() + versions = collection.versions.only("pk") _remove_collection_version_from_repos(versions) version_pks = versions.values_list("pk", flat=True)