87 lines
2.5 KiB
TypeScript
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 };
|
|
};
|