From 9c8bf1198650941b2098d135c6ff1784ff3ec350 Mon Sep 17 00:00:00 2001 From: Geert Rademakes Date: Fri, 8 Aug 2025 10:20:30 +0200 Subject: [PATCH] fix(background-jobs): poll job list continuously so newly started jobs appear immediately in the floating widget --- .../src/components/BackgroundJobProgress.tsx | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/packages/frontend/src/components/BackgroundJobProgress.tsx b/packages/frontend/src/components/BackgroundJobProgress.tsx index d7b9787..0d08576 100644 --- a/packages/frontend/src/components/BackgroundJobProgress.tsx +++ b/packages/frontend/src/components/BackgroundJobProgress.tsx @@ -92,25 +92,31 @@ export const BackgroundJobProgress: React.FC = ({ } }; - // Start polling for all active jobs + // Start polling for jobs and update progress const startPolling = () => { if (intervalRef.current) { clearInterval(intervalRef.current); } - intervalRef.current = setInterval(() => { - // Update all active jobs - const activeJobs = jobs.filter(job => job.status === 'running'); - const activeJobIds = activeJobs.map(job => job.jobId); - activeJobIds.forEach(jobId => { - updateJobProgress(jobId); - }); - - // Also update specific jobId if provided - if (jobId) { - updateJobProgress(jobId); + intervalRef.current = setInterval(async () => { + try { + // Always reload job list to detect newly started jobs + const jobsData = await api.getAllJobs(); + setJobs(jobsData); + + // Update progress for active jobs + const activeJobIds = jobsData.filter((j: JobProgress) => j.status === 'running').map((j: JobProgress) => j.jobId); + for (const id of activeJobIds) { + await updateJobProgress(id); + } + + if (jobId) { + await updateJobProgress(jobId); + } + } catch (err) { + // ignore transient polling errors } - }, 2000); // Poll every 2 seconds for less frequent updates + }, 2000); }; // Stop polling @@ -121,23 +127,13 @@ export const BackgroundJobProgress: React.FC = ({ } }; - // Load jobs on mount + // Start polling on mount and stop on unmount useEffect(() => { loadJobs(); + startPolling(); + return () => stopPolling(); }, []); - // Start polling for active jobs - useEffect(() => { - const activeJobs = jobs.filter(job => job.status === 'running'); - if (activeJobs.length > 0 || jobId) { - startPolling(); - } - - return () => { - stopPolling(); - }; - }, [jobs, jobId]); - // Cleanup on unmount useEffect(() => { return () => {