Skip to content

Commit e4c5237

Browse files
authored
Merge pull request #814 from getmaxun/dialog-fix
fix: socket conn handling
2 parents a60df7f + 6b7a1f8 commit e4c5237

File tree

4 files changed

+67
-89
lines changed

4 files changed

+67
-89
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,6 @@ export class WorkflowInterpreter {
625625
try {
626626
const sequelize = require('../../storage/db').default;
627627
await sequelize.transaction(async (transaction: any) => {
628-
const { Run } = require('../../models');
629628
const run = await Run.findOne({
630629
where: { runId: this.currentRunId! },
631630
transaction
@@ -690,6 +689,10 @@ export class WorkflowInterpreter {
690689
}
691690
} finally {
692691
this.persistenceInProgress = false;
692+
693+
if (this.persistenceBuffer.length > 0 && !this.persistenceTimer) {
694+
this.scheduleBatchFlush();
695+
}
693696
}
694697
};
695698
}

src/context/socket.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ interface SocketState {
99
queueSocket: Socket | null;
1010
id: string;
1111
setId: (id: string) => void;
12-
connectToQueueSocket: (userId: string, onRunCompleted?: (data: any) => void) => void;
12+
connectToQueueSocket: (userId: string, onRunCompleted?: (data: any) => void, onRunStarted?: (data: any) => void, onRunRecovered?: (data: any) => void, onRunScheduled?: (data: any) => void) => void;
1313
disconnectQueueSocket: () => void;
1414
};
1515

@@ -29,6 +29,9 @@ export const SocketProvider = ({ children }: { children: JSX.Element }) => {
2929
const [queueSocket, setQueueSocket] = useState<Socket | null>(socketStore.queueSocket);
3030
const [id, setActiveId] = useState<string>(socketStore.id);
3131
const runCompletedCallbackRef = useRef<((data: any) => void) | null>(null);
32+
const runStartedCallbackRef = useRef<((data: any) => void) | null>(null);
33+
const runRecoveredCallbackRef = useRef<((data: any) => void) | null>(null);
34+
const runScheduledCallbackRef = useRef<((data: any) => void) | null>(null);
3235

3336
const setId = useCallback((id: string) => {
3437
// the socket client connection is recomputed whenever id changes -> the new browser has been initialized
@@ -45,8 +48,11 @@ export const SocketProvider = ({ children }: { children: JSX.Element }) => {
4548
setActiveId(id);
4649
}, [setSocket]);
4750

48-
const connectToQueueSocket = useCallback((userId: string, onRunCompleted?: (data: any) => void) => {
51+
const connectToQueueSocket = useCallback((userId: string, onRunCompleted?: (data: any) => void, onRunStarted?: (data: any) => void, onRunRecovered?: (data: any) => void, onRunScheduled?: (data: any) => void) => {
4952
runCompletedCallbackRef.current = onRunCompleted || null;
53+
runStartedCallbackRef.current = onRunStarted || null;
54+
runRecoveredCallbackRef.current = onRunRecovered || null;
55+
runScheduledCallbackRef.current = onRunScheduled || null;
5056

5157
const newQueueSocket = io(`${SERVER_ENDPOINT}/queued-run`, {
5258
transports: ["websocket"],
@@ -69,6 +75,27 @@ export const SocketProvider = ({ children }: { children: JSX.Element }) => {
6975
}
7076
});
7177

78+
newQueueSocket.on('run-started', (startedData) => {
79+
console.log('Run started event received:', startedData);
80+
if (runStartedCallbackRef.current) {
81+
runStartedCallbackRef.current(startedData);
82+
}
83+
});
84+
85+
newQueueSocket.on('run-recovered', (recoveredData) => {
86+
console.log('Run recovered event received:', recoveredData);
87+
if (runRecoveredCallbackRef.current) {
88+
runRecoveredCallbackRef.current(recoveredData);
89+
}
90+
});
91+
92+
newQueueSocket.on('run-scheduled', (scheduledData) => {
93+
console.log('Run scheduled event received:', scheduledData);
94+
if (runScheduledCallbackRef.current) {
95+
runScheduledCallbackRef.current(scheduledData);
96+
}
97+
});
98+
7299
setQueueSocket(currentSocket => {
73100
if (currentSocket) {
74101
currentSocket.disconnect();
@@ -89,6 +116,8 @@ export const SocketProvider = ({ children }: { children: JSX.Element }) => {
89116

90117
socketStore.queueSocket = null;
91118
runCompletedCallbackRef.current = null;
119+
runRecoveredCallbackRef.current = null;
120+
runScheduledCallbackRef.current = null;
92121
}, []);
93122

94123
// Cleanup on unmount

src/helpers/clientSelectorGenerator.ts

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -3906,24 +3906,6 @@ class ClientSelectorGenerator {
39063906
let elements = iframeDoc.elementsFromPoint(x, y) as HTMLElement[];
39073907
if (!elements.length) return null;
39083908

3909-
const dialogElement = this.findDialogElement(elements);
3910-
if (dialogElement) {
3911-
const dialogRect = dialogElement.getBoundingClientRect();
3912-
const isClickInsideDialog = x >= dialogRect.left && x <= dialogRect.right &&
3913-
y >= dialogRect.top && y <= dialogRect.bottom;
3914-
3915-
if (isClickInsideDialog) {
3916-
const dialogElements = elements.filter(
3917-
(el) => el === dialogElement || dialogElement.contains(el)
3918-
);
3919-
3920-
const deepestInDialog = this.findDeepestInDialog(dialogElements, dialogElement);
3921-
if (deepestInDialog) {
3922-
return deepestInDialog;
3923-
}
3924-
}
3925-
}
3926-
39273909
const filteredElements = this.filterLogicalElements(elements, x, y);
39283910
const targetElements =
39293911
filteredElements.length > 0 ? filteredElements : elements;
@@ -4061,72 +4043,6 @@ class ClientSelectorGenerator {
40614043
return depth;
40624044
}
40634045

4064-
/**
4065-
* Find dialog element in the elements array
4066-
*/
4067-
private findDialogElement(elements: HTMLElement[]): HTMLElement | null {
4068-
let dialogElement = elements.find((el) => el.getAttribute("role") === "dialog");
4069-
4070-
if (!dialogElement) {
4071-
dialogElement = elements.find((el) => el.tagName.toLowerCase() === "dialog");
4072-
}
4073-
4074-
if (!dialogElement) {
4075-
dialogElement = elements.find((el) => {
4076-
const classList = el.classList.toString().toLowerCase();
4077-
const id = (el.id || "").toLowerCase();
4078-
4079-
return (
4080-
classList.includes("modal") ||
4081-
classList.includes("dialog") ||
4082-
classList.includes("popup") ||
4083-
classList.includes("overlay") ||
4084-
id.includes("modal") ||
4085-
id.includes("dialog") ||
4086-
id.includes("popup")
4087-
);
4088-
});
4089-
}
4090-
4091-
return dialogElement || null;
4092-
}
4093-
4094-
/**
4095-
* Find the deepest element within a dialog
4096-
*/
4097-
private findDeepestInDialog(
4098-
dialogElements: HTMLElement[],
4099-
dialogElement: HTMLElement
4100-
): HTMLElement | null {
4101-
if (!dialogElements.length) return null;
4102-
if (dialogElements.length === 1) return dialogElements[0];
4103-
4104-
let deepestElement = dialogElements[0];
4105-
let maxDepth = 0;
4106-
4107-
for (const element of dialogElements) {
4108-
let depth = 0;
4109-
let current = element;
4110-
4111-
// Calculate depth within the dialog context
4112-
while (
4113-
current &&
4114-
current.parentElement &&
4115-
current !== dialogElement.parentElement
4116-
) {
4117-
depth++;
4118-
current = current.parentElement;
4119-
}
4120-
4121-
if (depth > maxDepth) {
4122-
maxDepth = depth;
4123-
deepestElement = element;
4124-
}
4125-
}
4126-
4127-
return deepestElement;
4128-
}
4129-
41304046
/**
41314047
* Check if an element is a dialog
41324048
*/

src/pages/MainPage.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,14 @@ export const MainPage = ({ handleEditRecording, initialContent }: MainPageProps)
215215

216216
useEffect(() => {
217217
if (user?.id) {
218+
const handleRunStarted = (startedData: any) => {
219+
setRerenderRuns(true);
220+
invalidateRuns();
221+
222+
const robotName = startedData.robotName || 'Unknown Robot';
223+
notify('info', t('main_page.notifications.run_started', { name: robotName }));
224+
};
225+
218226
const handleRunCompleted = (completionData: any) => {
219227
setRerenderRuns(true);
220228
invalidateRuns();
@@ -235,14 +243,36 @@ export const MainPage = ({ handleEditRecording, initialContent }: MainPageProps)
235243
notify('error', t('main_page.notifications.interpretation_failed', { name: robotName }));
236244
}
237245
};
246+
247+
const handleRunRecovered = (recoveredData: any) => {
248+
setRerenderRuns(true);
249+
invalidateRuns();
250+
251+
if (queuedRuns.has(recoveredData.runId)) {
252+
setQueuedRuns(prev => {
253+
const newSet = new Set(prev);
254+
newSet.delete(recoveredData.runId);
255+
return newSet;
256+
});
257+
}
258+
259+
const robotName = recoveredData.robotName || 'Unknown Robot';
260+
notify('error', t('main_page.notifications.interpretation_failed', { name: robotName }));
261+
};
262+
263+
const handleRunScheduled = (scheduledData: any) => {
264+
setRerenderRuns(true);
265+
invalidateRuns();
266+
};
238267

239-
connectToQueueSocket(user.id, handleRunCompleted);
268+
connectToQueueSocket(user.id, handleRunCompleted, handleRunStarted, handleRunRecovered, handleRunScheduled);
240269

241270
return () => {
271+
console.log('Disconnecting persistent queue socket for user:', user.id);
242272
disconnectQueueSocket();
243273
};
244274
}
245-
}, [user?.id, connectToQueueSocket, disconnectQueueSocket, t, setRerenderRuns, queuedRuns, setQueuedRuns, invalidateRuns]);
275+
}, [user?.id, connectToQueueSocket, disconnectQueueSocket, t, setRerenderRuns, queuedRuns, setQueuedRuns]);
246276

247277
const DisplayContent = () => {
248278
switch (content) {

0 commit comments

Comments
 (0)