feat: transport authoritative workload projections
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0230c-b06c-7641-808a-e191b6d1da49
This commit is contained in:
parent
a090903cfc
commit
ab936a1e98
27 changed files with 1671 additions and 15 deletions
|
|
@ -19,6 +19,12 @@ from hub_core.runtime.repository_navigation_routes import (
|
|||
)
|
||||
from hub_core.runtime.store import InMemoryPortStore, PortStore
|
||||
from hub_core.runtime.validation import ContractValidator
|
||||
from hub_core.runtime.workload_projection import (
|
||||
WorkloadProjectionClient,
|
||||
WorkloadProjectionRejected,
|
||||
WorkloadProjectionService,
|
||||
)
|
||||
from hub_core.runtime.workload_projection_routes import create_workload_projection_router
|
||||
|
||||
|
||||
def create_app(
|
||||
|
|
@ -26,6 +32,7 @@ def create_app(
|
|||
settings: RuntimeSettings | None = None,
|
||||
port_store: PortStore | None = None,
|
||||
repo_projection_client: RepoProjectionClient | None = None,
|
||||
workload_projection_client: WorkloadProjectionClient | None = None,
|
||||
) -> FastAPI:
|
||||
resolved_settings = settings or RuntimeSettings.from_env()
|
||||
resolved_store = port_store or _create_store(resolved_settings)
|
||||
|
|
@ -34,6 +41,10 @@ def create_app(
|
|||
client=repo_projection_client,
|
||||
store=resolved_store,
|
||||
)
|
||||
workload_projection = WorkloadProjectionService(
|
||||
client=workload_projection_client,
|
||||
store=resolved_store,
|
||||
)
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(_: FastAPI):
|
||||
|
|
@ -44,6 +55,11 @@ def create_app(
|
|||
# The readiness dependency reports the rejected or absent
|
||||
# projection while the API remains available for diagnosis.
|
||||
pass
|
||||
if workload_projection_client is not None:
|
||||
try:
|
||||
await workload_projection.refresh()
|
||||
except WorkloadProjectionRejected:
|
||||
pass
|
||||
yield
|
||||
if owns_store and (closer := getattr(resolved_store, "aclose", None)):
|
||||
await closer()
|
||||
|
|
@ -63,6 +79,7 @@ def create_app(
|
|||
)
|
||||
app.state.contract_validator = ContractValidator()
|
||||
app.state.repository_navigation = repository_navigation
|
||||
app.state.workload_projection = workload_projection
|
||||
|
||||
@app.get("/healthz", response_model=HealthResponse, tags=["system"])
|
||||
async def healthz() -> HealthResponse:
|
||||
|
|
@ -76,6 +93,7 @@ def create_app(
|
|||
dependency_checks = {
|
||||
**await resolved_store.readiness_checks(),
|
||||
**await repository_navigation.readiness_checks(),
|
||||
**await workload_projection.readiness_checks(),
|
||||
}
|
||||
ready = resolved_settings.is_ready(resolved_store.backend_name) and all(
|
||||
value in {"ok", "not_applicable"} for value in dependency_checks.values()
|
||||
|
|
@ -90,6 +108,9 @@ def create_app(
|
|||
},
|
||||
)
|
||||
|
||||
# Exact projection routes precede the generic /projections/{projection_id}
|
||||
# route so Starlette dispatch cannot shadow them.
|
||||
app.include_router(create_workload_projection_router())
|
||||
app.include_router(create_ports_router())
|
||||
app.include_router(create_repository_navigation_router())
|
||||
app.include_router(create_compatibility_router())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue