Skip to content

Commit 9a2d60e

Browse files
committed
fix: render run immediately
1 parent e4c5237 commit 9a2d60e

File tree

5 files changed

+43
-11
lines changed

5 files changed

+43
-11
lines changed

server/src/pgboss-worker.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,12 @@ async function processRunExecution(job: Job<ExecuteRunData>) {
333333
// Schedule updates for Google Sheets and Airtable
334334
await triggerIntegrationUpdates(plainRun.runId, plainRun.robotMetaId);
335335

336+
// Flush any remaining persistence buffer before emitting socket event
337+
if (browser && browser.interpreter) {
338+
await browser.interpreter.flushPersistenceBuffer();
339+
logger.log('debug', `Flushed persistence buffer before emitting run-completed for run ${data.runId}`);
340+
}
341+
336342
const completionData = {
337343
runId: data.runId,
338344
robotMetaId: plainRun.robotMetaId,

server/src/workflow-management/classes/Interpreter.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ export class WorkflowInterpreter {
300300
this.socket.emit('log', `----- The interpretation finished with status: ${status} -----`, false);
301301

302302
logger.log('debug', `Interpretation finished`);
303+
304+
// Flush any remaining data in persistence buffer before completing
305+
await this.flushPersistenceBuffer();
306+
303307
this.interpreter = null;
304308
this.socket.emit('activePairId', -1);
305309
this.interpretationIsPaused = false;
@@ -606,9 +610,9 @@ export class WorkflowInterpreter {
606610

607611
/**
608612
* Flushes persistence buffer to database in a single transaction
609-
* @private
613+
* @public - Made public to allow external flush before socket emission
610614
*/
611-
private async flushPersistenceBuffer(): Promise<void> {
615+
public async flushPersistenceBuffer(): Promise<void> {
612616
if (this.persistenceBuffer.length === 0 || this.persistenceInProgress || !this.currentRunId) {
613617
return;
614618
}

src/components/run/RunsTable.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,14 @@ export const RunsTable: React.FC<RunsTableProps> = ({
276276
}, [debouncedSearch]);
277277

278278

279+
// Handle rerender requests using cache invalidation
279280
useEffect(() => {
280281
if (rerenderRuns) {
282+
// Invalidate cache to force refetch
281283
refetch();
282284
setRerenderRuns(false);
283285
}
284-
}, [rerenderRuns, setRerenderRuns, refetch]);
286+
}, [rerenderRuns, refetch, setRerenderRuns]);
285287

286288
const handleDelete = useCallback(() => {
287289
notify('success', t('runstable.notifications.delete_success'));
@@ -373,7 +375,7 @@ export const RunsTable: React.FC<RunsTableProps> = ({
373375
urlRunId={urlRunId}
374376
/>
375377
));
376-
}, [getPaginationState, accordionSortConfigs, expandedRows, handleRowExpand, handleDelete, currentInterpretationLog, abortRunHandler, runningRecordingName, urlRunId]);
378+
}, [paginationStates, runId, runningRecordingName, currentInterpretationLog, abortRunHandler, handleDelete, accordionSortConfigs]);
377379

378380
const renderSortIcon = useCallback((column: Column, robotMetaId: string) => {
379381
const sortConfig = accordionSortConfigs[robotMetaId];

src/context/socket.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ export const SocketProvider = ({ children }: { children: JSX.Element }) => {
115115
});
116116

117117
socketStore.queueSocket = null;
118+
runStartedCallbackRef.current = null;
118119
runCompletedCallbackRef.current = null;
119120
runRecoveredCallbackRef.current = null;
120121
runScheduledCallbackRef.current = null;

src/pages/MainPage.tsx

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export const MainPage = ({ handleEditRecording, initialContent }: MainPageProps)
5050
let aborted = false;
5151

5252
const { notify, setRerenderRuns, setRecordingId } = useGlobalInfoStore();
53-
const { invalidateRuns } = useCacheInvalidation();
53+
const { invalidateRuns, addOptimisticRun } = useCacheInvalidation();
5454
const navigate = useNavigate();
5555

5656
const { state } = useContext(AuthContext);
@@ -132,19 +132,34 @@ export const MainPage = ({ handleEditRecording, initialContent }: MainPageProps)
132132
setRerenderRuns(true);
133133
invalidateRuns();
134134
})
135-
}, [runningRecordingName, aborted, currentInterpretationLog, notify, setRerenderRuns, invalidateRuns]);
135+
}, [runningRecordingName, aborted, currentInterpretationLog, notify, setRerenderRuns]);
136136

137137
const debugMessageHandler = useCallback((msg: string) => {
138138
setCurrentInterpretationLog((prevState) =>
139139
prevState + '\n' + `[${new Date().toLocaleString()}] ` + msg);
140140
}, [currentInterpretationLog])
141141

142142
const handleRunRecording = useCallback((settings: RunSettings) => {
143+
// Add optimistic run to cache immediately
144+
const optimisticRun = {
145+
id: runningRecordingId,
146+
runId: `temp-${Date.now()}`, // Temporary ID until we get the real one
147+
status: 'running',
148+
name: runningRecordingName,
149+
startedAt: new Date().toISOString(),
150+
finishedAt: '',
151+
robotMetaId: runningRecordingId,
152+
log: 'Starting...',
153+
isOptimistic: true
154+
};
155+
156+
addOptimisticRun(optimisticRun);
157+
143158
createAndRunRecording(runningRecordingId, settings).then((response: CreateRunResponseWithQueue) => {
159+
invalidateRuns();
144160
const { browserId, runId, robotMetaId, queued } = response;
145161

146162
setIds({ browserId, runId, robotMetaId });
147-
invalidateRuns();
148163
navigate(`/runs/${robotMetaId}/run/${runId}`);
149164

150165
if (queued) {
@@ -160,8 +175,6 @@ export const MainPage = ({ handleEditRecording, initialContent }: MainPageProps)
160175

161176
socket.on('debugMessage', debugMessageHandler);
162177
socket.on('run-completed', (data) => {
163-
setRunningRecordingName('');
164-
setCurrentInterpretationLog('');
165178
setRerenderRuns(true);
166179
invalidateRuns();
167180

@@ -201,7 +214,13 @@ export const MainPage = ({ handleEditRecording, initialContent }: MainPageProps)
201214
socket.off('connect_error');
202215
socket.off('disconnect');
203216
}
204-
}, [runningRecordingName, sockets, ids, debugMessageHandler, user?.id, t, notify, setRerenderRuns, setQueuedRuns, navigate, setContent, setIds, invalidateRuns]);
217+
}, [runningRecordingName, sockets, ids, debugMessageHandler, user?.id, t, notify, setRerenderRuns, setQueuedRuns, navigate, setContent, setIds, invalidateRuns, addOptimisticRun, runningRecordingId]);
218+
219+
useEffect(() => {
220+
return () => {
221+
queuedRuns.clear();
222+
};
223+
}, []);
205224

206225
const handleScheduleRecording = async (settings: ScheduleSettings) => {
207226
const { message, runId }: ScheduleRunResponse = await scheduleStoredRecording(runningRecordingId, settings);
@@ -225,7 +244,7 @@ export const MainPage = ({ handleEditRecording, initialContent }: MainPageProps)
225244

226245
const handleRunCompleted = (completionData: any) => {
227246
setRerenderRuns(true);
228-
invalidateRuns();
247+
invalidateRuns(); // Invalidate cache to show completed run status
229248

230249
if (queuedRuns.has(completionData.runId)) {
231250
setQueuedRuns(prev => {

0 commit comments

Comments
 (0)