fix: expose runtime worker list endpoint
This commit is contained in:
parent
f79892baef
commit
2e2d7b7290
|
|
@ -22,8 +22,19 @@ pub(crate) async fn run(target: BackendRuntimeListTarget) -> Result<(), Box<dyn
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
if response.items.is_empty() {
|
if response.items.is_empty() {
|
||||||
|
let diagnostics = response
|
||||||
|
.diagnostics
|
||||||
|
.iter()
|
||||||
|
.map(|diagnostic| format!("{}: {}", diagnostic.code, diagnostic.message))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("; ");
|
||||||
|
let detail = if diagnostics.is_empty() {
|
||||||
|
"no backend diagnostics".to_string()
|
||||||
|
} else {
|
||||||
|
diagnostics
|
||||||
|
};
|
||||||
return Err(Box::new(io::Error::other(format!(
|
return Err(Box::new(io::Error::other(format!(
|
||||||
"Backend returned no runtime workers for workspace {}",
|
"Backend returned no runtime workers for workspace {} ({detail})",
|
||||||
response.workspace_id
|
response.workspace_id
|
||||||
))));
|
))));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -902,6 +902,26 @@ impl RuntimeRegistry {
|
||||||
RuntimeList::new(items, diagnostics)
|
RuntimeList::new(items, diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_workers_for_runtime(
|
||||||
|
&self,
|
||||||
|
runtime_id: &str,
|
||||||
|
limit: usize,
|
||||||
|
) -> Result<RuntimeList<WorkerSummary>, RuntimeRegistryError> {
|
||||||
|
validate_backend_identifier("runtime_id", runtime_id)?;
|
||||||
|
let runtime = self.runtime(runtime_id)?;
|
||||||
|
let worker_list = runtime.list_workers(limit);
|
||||||
|
let mut items: Vec<_> = worker_list
|
||||||
|
.items
|
||||||
|
.into_iter()
|
||||||
|
.filter(|worker| !is_retired_companion_worker(worker))
|
||||||
|
.take(limit)
|
||||||
|
.collect();
|
||||||
|
items.truncate(limit);
|
||||||
|
let mut diagnostics = worker_list.diagnostics;
|
||||||
|
diagnostics.truncate(MAX_DIAGNOSTICS);
|
||||||
|
Ok(RuntimeList::new(items, diagnostics))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn list_workers_for_host(
|
pub fn list_workers_for_host(
|
||||||
&self,
|
&self,
|
||||||
host_id: &str,
|
host_id: &str,
|
||||||
|
|
@ -3774,6 +3794,30 @@ mod tests {
|
||||||
assert_eq!(from_runtime_a.label, "worker from runtime a");
|
assert_eq!(from_runtime_a.label, "worker from runtime a");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn registry_worker_list_can_be_scoped_by_runtime_id() {
|
||||||
|
let registry = RuntimeRegistry::new(vec![
|
||||||
|
Arc::new(FixtureRuntime::with_worker(
|
||||||
|
"runtime-a",
|
||||||
|
"host-a",
|
||||||
|
"shared-worker",
|
||||||
|
"worker from runtime a",
|
||||||
|
)),
|
||||||
|
Arc::new(FixtureRuntime::with_worker(
|
||||||
|
"runtime-b",
|
||||||
|
"host-b",
|
||||||
|
"shared-worker",
|
||||||
|
"worker from runtime b",
|
||||||
|
)),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let listed = registry.list_workers_for_runtime("runtime-b", 10).unwrap();
|
||||||
|
assert_eq!(listed.items.len(), 1);
|
||||||
|
assert_eq!(listed.items[0].runtime_id, "runtime-b");
|
||||||
|
assert_eq!(listed.items[0].host_id, "host-b");
|
||||||
|
assert_eq!(listed.items[0].label, "worker from runtime b");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn registry_worker_lookup_reports_unknown_runtime_and_worker_separately() {
|
fn registry_worker_lookup_reports_unknown_runtime_and_worker_separately() {
|
||||||
let registry = RuntimeRegistry::new(vec![Arc::new(FixtureRuntime::with_worker(
|
let registry = RuntimeRegistry::new(vec![Arc::new(FixtureRuntime::with_worker(
|
||||||
|
|
|
||||||
|
|
@ -473,11 +473,11 @@ pub fn build_router(api: WorkspaceApi) -> Router {
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/api/runtimes/{runtime_id}/workers",
|
"/api/runtimes/{runtime_id}/workers",
|
||||||
post(create_runtime_worker),
|
get(list_runtime_workers).post(create_runtime_worker),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/api/w/{workspace_id}/runtimes/{runtime_id}/workers",
|
"/api/w/{workspace_id}/runtimes/{runtime_id}/workers",
|
||||||
post(scoped_create_runtime_worker),
|
get(scoped_list_runtime_workers).post(scoped_create_runtime_worker),
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/api/runtimes/{runtime_id}/config-bundles",
|
"/api/runtimes/{runtime_id}/config-bundles",
|
||||||
|
|
@ -2305,6 +2305,14 @@ async fn scoped_post_companion_cancel(
|
||||||
post_companion_cancel(State(api), Json(request)).await
|
post_companion_cancel(State(api), Json(request)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn scoped_list_runtime_workers(
|
||||||
|
State(api): State<WorkspaceApi>,
|
||||||
|
AxumPath(path): AxumPath<ScopedRuntimePath>,
|
||||||
|
) -> ApiResult<Json<RuntimeListResponse<WorkerSummary>>> {
|
||||||
|
validate_workspace_scope(&api, &path.workspace_id)?;
|
||||||
|
list_runtime_workers(State(api), AxumPath(path.runtime_id)).await
|
||||||
|
}
|
||||||
|
|
||||||
async fn scoped_create_runtime_worker(
|
async fn scoped_create_runtime_worker(
|
||||||
State(api): State<WorkspaceApi>,
|
State(api): State<WorkspaceApi>,
|
||||||
AxumPath(path): AxumPath<ScopedRuntimePath>,
|
AxumPath(path): AxumPath<ScopedRuntimePath>,
|
||||||
|
|
@ -3202,6 +3210,24 @@ fn reject_no_workdir_for_non_embedded_runtime(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn list_runtime_workers(
|
||||||
|
State(api): State<WorkspaceApi>,
|
||||||
|
AxumPath(runtime_id): AxumPath<String>,
|
||||||
|
) -> ApiResult<Json<RuntimeListResponse<WorkerSummary>>> {
|
||||||
|
let limit = api.config.max_records.min(200);
|
||||||
|
let worker_list = api
|
||||||
|
.runtime
|
||||||
|
.list_workers_for_runtime(&runtime_id, limit)
|
||||||
|
.map_err(|err| err.into_error())?;
|
||||||
|
Ok(Json(RuntimeListResponse {
|
||||||
|
workspace_id: api.workspace_id().to_string(),
|
||||||
|
limit,
|
||||||
|
items: worker_list.items,
|
||||||
|
source: "runtime_registry".to_string(),
|
||||||
|
diagnostics: worker_list.diagnostics,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
async fn create_runtime_worker(
|
async fn create_runtime_worker(
|
||||||
State(api): State<WorkspaceApi>,
|
State(api): State<WorkspaceApi>,
|
||||||
AxumPath(runtime_id): AxumPath<String>,
|
AxumPath(runtime_id): AxumPath<String>,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user