Bound assigned-issue reminder snapshots
CI / lint (pull_request) Successful in 1m30s
CI / build-release (pull_request) Successful in 5s
CI / release-candidate (pull_request) Has been skipped

This commit is contained in:
timmy committed 2026-08-13 10:24:23 +00:00
1 parent 880f60831a
commit 4410af09a6
2 files changed
+105 -12

No files matched your search

+32 -8
View File
@@ -403,15 +403,39 @@ async def work_page(stream: str, page: int = 1, limit: int = 50) -> dict:
}
async def assigned_issue_snapshot(*, limit: int = 50, max_pages: int = 20) -> dict:
async def assigned_issue_snapshot(
*,
limit: int = 50,
max_pages: int = 20,
max_concurrency: int = 4,
deadline_seconds: float = 5.0,
) -> dict:
"""Load a complete, bounded assigned-issue snapshot for deadline dispatch."""
items = []
for page in range(1, max_pages + 1):
result = await work_page("issue", page, limit)
items.extend(result["items"])
if not result["has_more"]:
return {"items": items, "complete": True}
return {"items": [], "complete": False}
async with asyncio.timeout(deadline_seconds):
first = await work_page("issue", 1, limit)
page_count = max(1, (first["total"] + limit - 1) // limit)
if page_count > max_pages:
raise ValueError("Assigned issue snapshot exceeds the scan limit")
semaphore = asyncio.Semaphore(max(1, max_concurrency))
async def load(page: int) -> dict:
async with semaphore:
return await work_page("issue", page, limit)
remaining = await asyncio.gather(
*(load(page) for page in range(2, page_count + 1))
)
pages = [first, *remaining]
if any(page.get("total") != first["total"] for page in pages[1:]):
raise ValueError("Assigned issue pagination changed during the scan")
items = [item for page in pages for item in page["items"]]
issue_ids = [
item.get("id") for item in items
if isinstance(item, dict) and isinstance(item.get("id"), int) and item["id"] > 0
]
if len(items) != first["total"] or len(set(issue_ids)) != first["total"]:
raise ValueError("Assigned issue snapshot has an incomplete issue set")
return {"items": items, "complete": True}
def _normalize_global_search_item(item: Any, kind: str) -> dict | None: