96 lines
3.0 KiB
TypeScript
96 lines
3.0 KiB
TypeScript
import { UserSolution } from '@/interfaces/exam';
|
|
import useExamStore from '@/stores/exam';
|
|
import { StateFlags } from '@/stores/exam/types';
|
|
import axios from 'axios';
|
|
import { SetStateAction, useEffect, useRef } from 'react';
|
|
|
|
type UseEvaluationPolling = (props: {
|
|
pendingExercises: string[],
|
|
setPendingExercises: React.Dispatch<SetStateAction<string[]>>,
|
|
}) => void;
|
|
|
|
const useEvaluationPolling: UseEvaluationPolling = ({
|
|
pendingExercises,
|
|
setPendingExercises,
|
|
}) => {
|
|
const {
|
|
flags, sessionId, user,
|
|
userSolutions, evaluated,
|
|
setEvaluated, setFlags
|
|
} = useExamStore();
|
|
|
|
const pollingTimeoutRef = useRef<NodeJS.Timeout>();
|
|
|
|
useEffect(() => {
|
|
return () => {
|
|
if (pollingTimeoutRef.current) {
|
|
clearTimeout(pollingTimeoutRef.current);
|
|
}
|
|
};
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!flags.pendingEvaluation || pendingExercises.length === 0) {
|
|
|
|
if (pollingTimeoutRef.current) {
|
|
clearTimeout(pollingTimeoutRef.current);
|
|
}
|
|
return;
|
|
}
|
|
|
|
const pollStatus = async () => {
|
|
try {
|
|
const { data } = await axios.get('/api/evaluate/status', {
|
|
params: {
|
|
sessionId,
|
|
userId: user,
|
|
exerciseIds: pendingExercises.join(',')
|
|
}
|
|
});
|
|
|
|
if (data.finishedExerciseIds.length > 0) {
|
|
const remainingExercises = pendingExercises.filter(
|
|
id => !data.finishedExerciseIds.includes(id)
|
|
);
|
|
|
|
setPendingExercises(remainingExercises);
|
|
|
|
if (remainingExercises.length === 0) {
|
|
const evaluatedData = await axios.post('/api/evaluate/fetchSolutions', {
|
|
sessionId,
|
|
userId: user,
|
|
userSolutions
|
|
});
|
|
|
|
const newEvaluations = evaluatedData.data.filter(
|
|
(newEval: UserSolution) =>
|
|
!evaluated.some(existingEval => existingEval.exercise === newEval.exercise)
|
|
);
|
|
|
|
setEvaluated([...evaluated, ...newEvaluations]);
|
|
setFlags({ pendingEvaluation: false });
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (pendingExercises.length > 0) {
|
|
pollingTimeoutRef.current = setTimeout(pollStatus, 5000);
|
|
}
|
|
} catch (error) {
|
|
console.error('Evaluation polling error:', error);
|
|
pollingTimeoutRef.current = setTimeout(pollStatus, 5000);
|
|
}
|
|
};
|
|
|
|
pollStatus();
|
|
|
|
return () => {
|
|
if (pollingTimeoutRef.current) {
|
|
clearTimeout(pollingTimeoutRef.current);
|
|
}
|
|
};
|
|
});
|
|
};
|
|
|
|
export default useEvaluationPolling;
|