wing-ops/frontend/src/tabs/prediction/hooks/useSimulationStatus.ts

87 lines
2.5 KiB
TypeScript

import { useQuery, useQueries } from '@tanstack/react-query';
import { api } from '@common/services/api';
import type { SimulationStatusResponse } from '../services/predictionApi';
export const useSimulationStatus = (execSn: number | null) => {
return useQuery<SimulationStatusResponse>({
queryKey: ['simulationStatus', execSn],
queryFn: () => api.get<SimulationStatusResponse>(`/simulation/status/${execSn}`).then(r => r.data),
enabled: execSn !== null,
refetchInterval: (query) => {
const status = query.state.data?.status;
if (status === 'DONE' || status === 'ERROR') return false;
return 3000;
},
});
};
export interface ModelExecRef {
model: string;
execSn: number;
}
interface MultiSimulationStatus {
allDone: boolean;
anyError: boolean;
isLoading: boolean;
results: Map<string, SimulationStatusResponse>;
errors: Map<string, string>;
}
export const useMultiSimulationStatus = (execSns: ModelExecRef[]): MultiSimulationStatus => {
const queries = useQueries({
queries: execSns.map(({ model, execSn }) => ({
queryKey: ['simulationStatus', execSn],
queryFn: () =>
api.get<SimulationStatusResponse>(`/simulation/status/${execSn}`).then(r => r.data),
enabled: execSns.length > 0,
refetchInterval: (query: { state: { data?: SimulationStatusResponse } }) => {
const status = query.state.data?.status;
if (status === 'DONE' || status === 'ERROR') return false;
return 3000;
},
meta: { model },
})),
});
if (execSns.length === 0) {
return {
allDone: false,
anyError: false,
isLoading: false,
results: new Map(),
errors: new Map(),
};
}
const results = new Map<string, SimulationStatusResponse>();
const errors = new Map<string, string>();
execSns.forEach(({ model }, index) => {
const query = queries[index];
if (query.data) {
results.set(model, query.data);
}
if (query.error) {
const err = query.error;
errors.set(model, err instanceof Error ? err.message : String(err));
}
});
const allDone =
execSns.length > 0 &&
execSns.every((_, index) => {
const status = queries[index].data?.status;
return status === 'DONE' || status === 'ERROR';
});
const anyError = execSns.some((_, index) => {
const status = queries[index].data?.status;
return status === 'ERROR' || queries[index].isError;
});
const isLoading = execSns.some((_, index) => queries[index].isLoading);
return { allDone, anyError, isLoading, results, errors };
};