prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Global tasks like repair or reclaim should probably not run in parallel
  **Version**
  Please provide the versions of the pulpcore and plugin packages in use, and how they are installed.  If you are using Pulp via Katello, please provide the Katello version.
  
  **Describe the bug**
  Global tasks that involve all repos like repair or reclaim should run one at a time, like orphan cleanup https://github.com/pulp/pulpcore/blob/main/pulpcore/app/viewsets/orphans.py#L29
  
  **To Reproduce**
  Steps to reproduce the behavior:
  
  **Expected behavior**
  A clear and concise description of what you expected to happen.
  
  **Additional context**
  Add any other context about the problem here.  Please provide links to any previous discussions via Discourse or Bugzilla.
  
  
  </issue>
  <code>
  [start of pulpcore/app/views/repair.py]
  1 from drf_spectacular.utils import extend_schema
  2 from rest_framework.views import APIView
  3 
  4 from pulpcore.app.response import OperationPostponedResponse
  5 from pulpcore.app.serializers import AsyncOperationResponseSerializer, RepairSerializer
  6 from pulpcore.app.tasks import repair_all_artifacts
  7 from pulpcore.tasking.tasks import dispatch
  8 
  9 
  10 class RepairView(APIView):
  11     @extend_schema(
  12         description=(
  13             "Trigger an asynchronous task that checks for missing "
  14             "or corrupted artifacts, and attempts to redownload them."
  15         ),
  16         summary="Repair Artifact Storage",
  17         request=RepairSerializer,
  18         responses={202: AsyncOperationResponseSerializer},
  19     )
  20     def post(self, request):
  21         """
  22         Repair artifacts.
  23         """
  24         serializer = RepairSerializer(data=request.data)
  25         serializer.is_valid(raise_exception=True)
  26 
  27         verify_checksums = serializer.validated_data["verify_checksums"]
  28 
  29         task = dispatch(repair_all_artifacts, args=[verify_checksums])
  30 
  31         return OperationPostponedResponse(task, request)
  32
  [end of pulpcore/app/views/repair.py]
  [start of pulpcore/app/viewsets/reclaim.py]
  1 from drf_spectacular.utils import extend_schema
  2 from rest_framework.viewsets import ViewSet
  3 
  4 from pulpcore.app.response import OperationPostponedResponse
  5 from pulpcore.app.serializers import AsyncOperationResponseSerializer, ReclaimSpaceSerializer
  6 from pulpcore.app.tasks import reclaim_space
  7 from pulpcore.tasking.tasks import dispatch
  8 
  9 
  10 class ReclaimSpaceViewSet(ViewSet):
  11     """
  12     Viewset for reclaim disk space endpoint.
  13     """
  14 
  15     serializer_class = ReclaimSpaceSerializer
  16 
  17     @extend_schema(
  18         description="Trigger an asynchronous space reclaim operation.",
  19         responses={202: AsyncOperationResponseSerializer},
  20     )
  21     def reclaim(self, request):
  22         """
  23         Triggers an asynchronous space reclaim operation.
  24         """
  25         serializer = ReclaimSpaceSerializer(data=request.data)
  26         serializer.is_valid(raise_exception=True)
  27 
  28         repos = serializer.validated_data.get("repo_hrefs", [])
  29         keeplist = serializer.validated_data.get("repo_versions_keeplist", [])
  30         reclaim_repo_pks = []
  31         keeplist_rv_pks = []
  32         for repo in repos:
  33             reclaim_repo_pks.append(repo.pk)
  34         for rv in keeplist:
  35             repos.append(rv.repository)
  36             keeplist_rv_pks.append(rv.pk)
  37 
  38         task = dispatch(
  39             reclaim_space,
  40             shared_resources=repos,
  41             kwargs={
  42                 "repo_pks": reclaim_repo_pks,
  43                 "keeplist_rv_pks": keeplist_rv_pks,
  44             },
  45         )
  46 
  47         return OperationPostponedResponse(task, request)
  48
  [end of pulpcore/app/viewsets/reclaim.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/pulpcore/app/views/repair.py b/pulpcore/app/views/repair.py
  --- a/pulpcore/app/views/repair.py
  +++ b/pulpcore/app/views/repair.py
  @@ -1,4 +1,5 @@
   from drf_spectacular.utils import extend_schema
  +from django.conf import settings
   from rest_framework.views import APIView
   
   from pulpcore.app.response import OperationPostponedResponse
  @@ -26,6 +27,9 @@
   
           verify_checksums = serializer.validated_data["verify_checksums"]
   
  -        task = dispatch(repair_all_artifacts, args=[verify_checksums])
  +        uri = "/api/v3/repair/"
  +        if settings.DOMAIN_ENABLED:
  +            uri = f"/{request.pulp_domain.name}{uri}"
  +        task = dispatch(repair_all_artifacts, exclusive_resources=[uri], args=[verify_checksums])
   
           return OperationPostponedResponse(task, request)
  diff --git a/pulpcore/app/viewsets/reclaim.py b/pulpcore/app/viewsets/reclaim.py
  --- a/pulpcore/app/viewsets/reclaim.py
  +++ b/pulpcore/app/viewsets/reclaim.py
  @@ -1,4 +1,5 @@
   from drf_spectacular.utils import extend_schema
  +from django.conf import settings
   from rest_framework.viewsets import ViewSet
   
   from pulpcore.app.response import OperationPostponedResponse
  @@ -35,8 +36,17 @@
               repos.append(rv.repository)
               keeplist_rv_pks.append(rv.pk)
   
  +        if repos:
  +            exclusive_resources = None
  +        else:
  +            uri = "/api/v3/repositories/reclaim_space/"
  +            if settings.DOMAIN_ENABLED:
  +                uri = f"/{request.pulp_domain.name}{uri}"
  +            exclusive_resources = [uri]
  +
           task = dispatch(
               reclaim_space,
  +            exclusive_resources=exclusive_resources,
               shared_resources=repos,
               kwargs={
                   "repo_pks": reclaim_repo_pks,
  
verification_info: {"golden_diff": "diff --git a/pulpcore/app/views/repair.py b/pulpcore/app/views/repair.py\n--- a/pulpcore/app/views/repair.py\n+++ b/pulpcore/app/views/repair.py\n@@ -1,4 +1,5 @@\n from drf_spectacular.utils import extend_schema\n+from django.conf import settings\n from rest_framework.views import APIView\n \n from pulpcore.app.response import OperationPostponedResponse\n@@ -26,6 +27,9 @@\n \n         verify_checksums = serializer.validated_data[\"verify_checksums\"]\n \n-        task = dispatch(repair_all_artifacts, args=[verify_checksums])\n+        uri = \"/api/v3/repair/\"\n+        if settings.DOMAIN_ENABLED:\n+            uri = f\"/{request.pulp_domain.name}{uri}\"\n+        task = dispatch(repair_all_artifacts, exclusive_resources=[uri], args=[verify_checksums])\n \n         return OperationPostponedResponse(task, request)\ndiff --git a/pulpcore/app/viewsets/reclaim.py b/pulpcore/app/viewsets/reclaim.py\n--- a/pulpcore/app/viewsets/reclaim.py\n+++ b/pulpcore/app/viewsets/reclaim.py\n@@ -1,4 +1,5 @@\n from drf_spectacular.utils import extend_schema\n+from django.conf import settings\n from rest_framework.viewsets import ViewSet\n \n from pulpcore.app.response import OperationPostponedResponse\n@@ -35,8 +36,17 @@\n             repos.append(rv.repository)\n             keeplist_rv_pks.append(rv.pk)\n \n+        if repos:\n+            exclusive_resources = None\n+        else:\n+            uri = \"/api/v3/repositories/reclaim_space/\"\n+            if settings.DOMAIN_ENABLED:\n+                uri = f\"/{request.pulp_domain.name}{uri}\"\n+            exclusive_resources = [uri]\n+\n         task = dispatch(\n             reclaim_space,\n+            exclusive_resources=exclusive_resources,\n             shared_resources=repos,\n             kwargs={\n                 \"repo_pks\": reclaim_repo_pks,\n", "issue": "Global tasks like repair or reclaim should probably not run in parallel\n**Version**\r\nPlease provide the versions of the pulpcore and plugin packages in use, and how they are installed.  If you are using Pulp via Katello, please provide the Katello version.\r\n\r\n**Describe the bug**\r\nGlobal tasks that involve all repos like repair or reclaim should run one at a time, like orphan cleanup https://github.com/pulp/pulpcore/blob/main/pulpcore/app/viewsets/orphans.py#L29\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n\r\n**Expected behavior**\r\nA clear and concise description of what you expected to happen.\r\n\r\n**Additional context**\r\nAdd any other context about the problem here.  Please provide links to any previous discussions via Discourse or Bugzilla.\r\n\n", "before_files": [{"content": "from drf_spectacular.utils import extend_schema\nfrom rest_framework.views import APIView\n\nfrom pulpcore.app.response import OperationPostponedResponse\nfrom pulpcore.app.serializers import AsyncOperationResponseSerializer, RepairSerializer\nfrom pulpcore.app.tasks import repair_all_artifacts\nfrom pulpcore.tasking.tasks import dispatch\n\n\nclass RepairView(APIView):\n    @extend_schema(\n        description=(\n            \"Trigger an asynchronous task that checks for missing \"\n            \"or corrupted artifacts, and attempts to redownload them.\"\n        ),\n        summary=\"Repair Artifact Storage\",\n        request=RepairSerializer,\n        responses={202: AsyncOperationResponseSerializer},\n    )\n    def post(self, request):\n        \"\"\"\n        Repair artifacts.\n        \"\"\"\n        serializer = RepairSerializer(data=request.data)\n        serializer.is_valid(raise_exception=True)\n\n        verify_checksums = serializer.validated_data[\"verify_checksums\"]\n\n        task = dispatch(repair_all_artifacts, args=[verify_checksums])\n\n        return OperationPostponedResponse(task, request)\n", "path": "pulpcore/app/views/repair.py"}, {"content": "from drf_spectacular.utils import extend_schema\nfrom rest_framework.viewsets import ViewSet\n\nfrom pulpcore.app.response import OperationPostponedResponse\nfrom pulpcore.app.serializers import AsyncOperationResponseSerializer, ReclaimSpaceSerializer\nfrom pulpcore.app.tasks import reclaim_space\nfrom pulpcore.tasking.tasks import dispatch\n\n\nclass ReclaimSpaceViewSet(ViewSet):\n    \"\"\"\n    Viewset for reclaim disk space endpoint.\n    \"\"\"\n\n    serializer_class = ReclaimSpaceSerializer\n\n    @extend_schema(\n        description=\"Trigger an asynchronous space reclaim operation.\",\n        responses={202: AsyncOperationResponseSerializer},\n    )\n    def reclaim(self, request):\n        \"\"\"\n        Triggers an asynchronous space reclaim operation.\n        \"\"\"\n        serializer = ReclaimSpaceSerializer(data=request.data)\n        serializer.is_valid(raise_exception=True)\n\n        repos = serializer.validated_data.get(\"repo_hrefs\", [])\n        keeplist = serializer.validated_data.get(\"repo_versions_keeplist\", [])\n        reclaim_repo_pks = []\n        keeplist_rv_pks = []\n        for repo in repos:\n            reclaim_repo_pks.append(repo.pk)\n        for rv in keeplist:\n            repos.append(rv.repository)\n            keeplist_rv_pks.append(rv.pk)\n\n        task = dispatch(\n            reclaim_space,\n            shared_resources=repos,\n            kwargs={\n                \"repo_pks\": reclaim_repo_pks,\n                \"keeplist_rv_pks\": keeplist_rv_pks,\n            },\n        )\n\n        return OperationPostponedResponse(task, request)\n", "path": "pulpcore/app/viewsets/reclaim.py"}]}