Repository: pulp/pulpcore

Issue:
Task list and show endpoint optimizations for created_resources regress with domains
created_resources always render with "default" domain.


Discussion:

Resolving patch:
diff --git a/pulpcore/app/serializers/base.py b/pulpcore/app/serializers/base.py
--- a/pulpcore/app/serializers/base.py
+++ b/pulpcore/app/serializers/base.py
@@ -155,7 +155,8 @@ class RelatedField(
     """
 
 
-PKOnlyObject = namedtuple("PKOnlyObject", ["pk"])
+PKObject = namedtuple("PKObject", ["pk"])
+PKDomainObject = namedtuple("PKDomainObject", ["pk", "pulp_domain"])
 
 
 class RelatedResourceField(RelatedField):
@@ -171,7 +172,7 @@ class RelatedResourceField(RelatedField):
     def repo_ver_url(self, repo_ver):
         repo_model = get_model_for_pulp_type(repo_ver.repository.pulp_type, Repository)
         view_name = get_view_name_for_model(repo_model, "detail")
-        obj = PKOnlyObject(pk=repo_ver.repository.pk)
+        obj = PKDomainObject(pk=repo_ver.repository.pk, pulp_domain=self.context["pulp_domain"])
         repo_url = self.get_url(obj, view_name, request=None, format=None)
         return f"{repo_url}versions/{repo_ver.number}/"
 
@@ -192,7 +193,12 @@ def to_representation(self, data):
                 except LookupError:
                     pass
                 else:
-                    obj = PKOnlyObject(pk=data.object_id)
+                    if hasattr(model, "pulp_domain"):
+                        obj = PKDomainObject(
+                            pk=data.object_id, pulp_domain=self.context["pulp_domain"]
+                        )
+                    else:
+                        obj = PKObject(pk=data.object_id)
                     try:
                         return self.get_url(obj, view_name, request=None, format=None)
                     except NoReverseMatch:
diff --git a/pulpcore/app/viewsets/task.py b/pulpcore/app/viewsets/task.py
--- a/pulpcore/app/viewsets/task.py
+++ b/pulpcore/app/viewsets/task.py
@@ -29,6 +29,7 @@
     WorkerSerializer,
 )
 from pulpcore.app.tasks import purge
+from pulpcore.app.util import get_domain
 from pulpcore.app.viewsets import NamedModelViewSet, RolesMixin
 from pulpcore.app.viewsets.base import DATETIME_FILTER_OPTIONS, NAME_FILTER_OPTIONS
 from pulpcore.app.viewsets.custom_filters import (
@@ -39,7 +40,7 @@
 )
 from pulpcore.constants import TASK_INCOMPLETE_STATES, TASK_STATES
 from pulpcore.tasking.tasks import dispatch
-from pulpcore.tasking.util import cancel as cancel_task
+from pulpcore.tasking.util import cancel_task
 
 
 class TaskFilter(BaseFilterSet):
@@ -167,6 +168,8 @@ def get_serializer(self, *args, **kwargs):
                 .only("pk", "number", "repository__pulp_type")
             )
             serializer.context["repo_ver_mapping"] = {rv.pk: rv for rv in repo_vers}
+            # Assume, all tasks and related resources are of the same domain.
+            serializer.context["pulp_domain"] = get_domain()
         return serializer
 
     def get_queryset(self):
diff --git a/pulpcore/tasking/util.py b/pulpcore/tasking/util.py
--- a/pulpcore/tasking/util.py
+++ b/pulpcore/tasking/util.py
@@ -10,7 +10,7 @@
 _logger = logging.getLogger(__name__)
 
 
-def cancel(task_id):
+def cancel_task(task_id):
     """
     Cancel the task that is represented by the given task_id.
 


Test patch:
diff --git a/pulpcore/tests/functional/__init__.py b/pulpcore/tests/functional/__init__.py
--- a/pulpcore/tests/functional/__init__.py
+++ b/pulpcore/tests/functional/__init__.py
@@ -12,6 +12,7 @@
 import pytest
 
 from aiohttp import web
+from contextlib import suppress
 from dataclasses import dataclass
 from packaging.version import parse as parse_version
 from time import sleep
@@ -929,7 +930,9 @@ def _add_to_cleanup(api_client, pulp_href):
             pass
 
     for deleted_task_href in delete_task_hrefs:
-        monitor_task(deleted_task_href)
+        with suppress(ApiException):
+            # The task itself may be gone at this point (e.g. by being part of a deleted domain).
+            monitor_task(deleted_task_href)
 
 
 @pytest.fixture(scope="class")