37 lines
1.1 KiB
Python
37 lines
1.1 KiB
Python
"""Deterministic worker routing for candidate autonomous release workflows."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from .errors import CapabilityMismatch
|
|
from .models import WorkerDescriptor
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class RouteRequest:
|
|
task_id: str
|
|
required_capabilities: tuple[str, ...]
|
|
trust_zone: str
|
|
|
|
|
|
class WorkerRouter:
|
|
"""Select the least loaded compatible worker without expanding trust."""
|
|
|
|
def __init__(self, workers: list[WorkerDescriptor]) -> None:
|
|
self._workers = list(workers)
|
|
|
|
def route(self, request: RouteRequest) -> WorkerDescriptor:
|
|
candidates = [
|
|
worker
|
|
for worker in self._workers
|
|
if worker.can_accept(request.required_capabilities, request.trust_zone)
|
|
]
|
|
if not candidates:
|
|
raise CapabilityMismatch(
|
|
"NO_COMPATIBLE_WORKER",
|
|
"no worker satisfies capability and trust constraints",
|
|
{"task_id": request.task_id},
|
|
)
|
|
return sorted(candidates, key=lambda item: (item.current_load, item.worker_id))[0]
|