feat: implement polling fallback for SSE connection failures and add event deduplication
This commit is contained in:
@@ -172,7 +172,9 @@ export function HomePage() {
|
||||
let eventSource: EventSource | null = null;
|
||||
let reconnectTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
let reconnectAttempts = 0;
|
||||
const maxReconnectAttempts = 5;
|
||||
const maxReconnectAttempts = 3;
|
||||
let lastEventId: string | null = null;
|
||||
let pollInterval: ReturnType<typeof setInterval> | null = null;
|
||||
|
||||
const connect = () => {
|
||||
if (eventSource) {
|
||||
@@ -180,7 +182,8 @@ export function HomePage() {
|
||||
}
|
||||
|
||||
if (reconnectAttempts >= maxReconnectAttempts) {
|
||||
console.log('[SSE] Max reconnect attempts reached');
|
||||
console.log('[SSE] Max reconnect attempts reached, switching to polling');
|
||||
startPolling();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -191,30 +194,46 @@ export function HomePage() {
|
||||
eventSource.onerror = () => {
|
||||
if (eventSource?.readyState === EventSource.CLOSED) {
|
||||
reconnectAttempts++;
|
||||
const delay = Math.min(1000 * 2 ** reconnectAttempts, 30000);
|
||||
console.log(
|
||||
`[SSE] Connection closed, retry ${reconnectAttempts}/${maxReconnectAttempts} in ${delay}ms`
|
||||
`[SSE] Connection closed, retry ${reconnectAttempts}/${maxReconnectAttempts}`
|
||||
);
|
||||
reconnectTimeout = setTimeout(() => {
|
||||
connect();
|
||||
}, delay);
|
||||
}, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
eventSource.addEventListener('message', (event) => {
|
||||
if (event.data && event.data !== 'connected' && event.data !== 'ping') {
|
||||
if (event.data !== lastEventId) {
|
||||
lastEventId = event.data;
|
||||
reconnectAttempts = 0;
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin-bookings', selectedComplex.id] });
|
||||
void queryClient.invalidateQueries({
|
||||
queryKey: ['admin-bookings', selectedComplex.id],
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const startPolling = () => {
|
||||
if (pollInterval) return;
|
||||
|
||||
console.log('[SSE] Starting polling fallback');
|
||||
pollInterval = setInterval(() => {
|
||||
void queryClient.invalidateQueries({ queryKey: ['admin-bookings', selectedComplex.id] });
|
||||
}, 10000);
|
||||
};
|
||||
|
||||
connect();
|
||||
|
||||
return () => {
|
||||
if (reconnectTimeout) {
|
||||
clearTimeout(reconnectTimeout);
|
||||
}
|
||||
if (pollInterval) {
|
||||
clearInterval(pollInterval);
|
||||
}
|
||||
eventSource?.close();
|
||||
};
|
||||
}, [selectedComplex?.id, queryClient]);
|
||||
|
||||
Reference in New Issue
Block a user