Skip to content

Commit d5eabc8

Browse files
jopemachineclaude
andcommitted
fix(BA-5829): drop Fragment batch_load_by_ids; route loader through admin_search
Per review: the Fragment adapter's `batch_load_by_ids` duplicates the search action; route the DataLoader through the existing `admin_search` adapter method using the new `id_in` filter (added in BA-5827) instead. The DataLoader still preserves the input order and the Relay None-for- missing contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0db33aa commit d5eabc8

2 files changed

Lines changed: 14 additions & 31 deletions

File tree

src/ai/backend/manager/api/adapters/app_config_fragment.py

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
from __future__ import annotations
44

5-
import uuid
6-
from collections.abc import Sequence
7-
85
from ai.backend.common.contexts.user import current_user
96
from ai.backend.common.dto.manager.v2.app_config.request import (
107
AppConfigFilter,
@@ -77,7 +74,6 @@
7774
)
7875
from ai.backend.manager.repositories.base import (
7976
BatchQuerier,
80-
OffsetPagination,
8177
QueryCondition,
8278
QueryOrder,
8379
)
@@ -128,31 +124,6 @@
128124
class AppConfigFragmentAdapter(BaseAdapter):
129125
"""Adapter for AppConfigFragment domain operations (BEP-1052 §2)."""
130126

131-
async def batch_load_by_ids(
132-
self, ids: Sequence[uuid.UUID]
133-
) -> list[AppConfigFragmentNode | None]:
134-
"""Batch-load fragments by id for DataLoader use.
135-
136-
Returns `AppConfigFragmentNode` DTOs in the same order as the
137-
input `ids`, with `None` placeholders for rows that do not
138-
exist (Relay batching contract). Goes through the cross-scope
139-
search action because the scope-bound variant requires a single
140-
`(scope_type, scope_id)` slice — DataLoader batches span
141-
scopes. Authorization for the overall query is enforced at the
142-
parent resolver before this loader is invoked.
143-
"""
144-
if not ids:
145-
return []
146-
querier = BatchQuerier(
147-
pagination=OffsetPagination(limit=len(ids)),
148-
conditions=[AppConfigFragmentConditions.by_ids(ids)],
149-
)
150-
result = await self._processors.app_config_fragment.admin_search.wait_for_complete(
151-
AdminSearchAppConfigFragmentsAction(querier=querier)
152-
)
153-
by_id = {item.id: self._data_to_dto(item) for item in result.items}
154-
return [by_id.get(fragment_id) for fragment_id in ids]
155-
156127
async def create(self, input: CreateAppConfigFragmentInput) -> CreateAppConfigFragmentPayload:
157128
key = self._input_to_key(input.key)
158129
result = await self._processors.app_config_fragment.create.wait_for_complete(

src/ai/backend/manager/api/gql/data_loader/data_loaders.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,24 @@ def app_config_fragment_loader(
123123
adapter = self._adapters.app_config_fragment
124124

125125
async def load_fn(ids: list[uuid.UUID]) -> list[AppConfigFragmentGQL | None]:
126+
from ai.backend.common.dto.manager.v2.app_config_fragment.request import ( # pants: no-infer-dep
127+
AppConfigFragmentFilter,
128+
SearchAppConfigFragmentsInput,
129+
)
126130
from ai.backend.manager.api.gql.app_config_fragment.types import ( # pants: no-infer-dep
127131
AppConfigFragmentGQL as F,
128132
)
129133

130-
dtos = await adapter.batch_load_by_ids(ids)
131-
return [F.from_pydantic(dto) if dto is not None else None for dto in dtos]
134+
if not ids:
135+
return []
136+
payload = await adapter.admin_search(
137+
SearchAppConfigFragmentsInput(
138+
filter=AppConfigFragmentFilter(id_in=list(ids)),
139+
limit=len(ids),
140+
),
141+
)
142+
by_id = {dto.id: F.from_pydantic(dto) for dto in payload.items}
143+
return [by_id.get(fragment_id) for fragment_id in ids]
132144

133145
return DataLoader(load_fn=load_fn)
134146

0 commit comments

Comments
 (0)