Ignore aborted satellite pass requests

This commit is contained in:
James Smith
2026-03-19 08:04:36 +00:00
parent 5486656782
commit 09e0ddef79
+42 -4
View File
@@ -602,6 +602,8 @@
let _txRequestId = 0; let _txRequestId = 0;
let _telemetryPollTimer = null; let _telemetryPollTimer = null;
let _passRequestId = 0; let _passRequestId = 0;
let _passAbortController = null;
let _passTimeoutId = null;
const DASHBOARD_FETCH_TIMEOUT_MS = 10000; const DASHBOARD_FETCH_TIMEOUT_MS = 10000;
const BUILTIN_TX_FALLBACK = { const BUILTIN_TX_FALLBACK = {
25544: [ 25544: [
@@ -911,6 +913,16 @@
// Refresh satellite list when the window regains focus (e.g. after enabling sats in the sidebar) // Refresh satellite list when the window regains focus (e.g. after enabling sats in the sidebar)
window.addEventListener('focus', loadDashboardSatellites); window.addEventListener('focus', loadDashboardSatellites);
window.addEventListener('pagehide', () => {
if (_passAbortController) {
_passAbortController.abort('pagehide');
_passAbortController = null;
}
if (_passTimeoutId) {
clearTimeout(_passTimeoutId);
_passTimeoutId = null;
}
});
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
loadDashboardSatellites(); loadDashboardSatellites();
@@ -1131,9 +1143,19 @@
button.textContent = 'WORKING...'; button.textContent = 'WORKING...';
} }
if (_passAbortController) {
_passAbortController.abort('superseded');
_passAbortController = null;
}
if (_passTimeoutId) {
clearTimeout(_passTimeoutId);
_passTimeoutId = null;
}
try { try {
const controller = new AbortController(); const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), DASHBOARD_FETCH_TIMEOUT_MS); _passAbortController = controller;
_passTimeoutId = setTimeout(() => controller.abort('timeout'), DASHBOARD_FETCH_TIMEOUT_MS);
const response = await fetch('/satellite/predict', { const response = await fetch('/satellite/predict', {
method: 'POST', method: 'POST',
credentials: 'same-origin', credentials: 'same-origin',
@@ -1147,7 +1169,13 @@
satellites: [selectedSatellite] satellites: [selectedSatellite]
}) })
}); });
clearTimeout(timeout); if (_passTimeoutId) {
clearTimeout(_passTimeoutId);
_passTimeoutId = null;
}
if (_passAbortController === controller) {
_passAbortController = null;
}
const contentType = response.headers.get('Content-Type') || ''; const contentType = response.headers.get('Content-Type') || '';
if (!contentType.includes('application/json')) { if (!contentType.includes('application/json')) {
@@ -1178,12 +1206,22 @@
} }
} }
} catch (err) { } catch (err) {
const isAbort = err && (err.name === 'AbortError' || String(err).includes('AbortError'));
if (_passTimeoutId) {
clearTimeout(_passTimeoutId);
_passTimeoutId = null;
}
if (_passAbortController && _passAbortController.signal.aborted) {
_passAbortController = null;
}
if (requestId !== _passRequestId) return; if (requestId !== _passRequestId) return;
if (isAbort) {
return;
}
console.error('Pass calculation error:', err); console.error('Pass calculation error:', err);
passes = []; passes = [];
if (container) { if (container) {
const timedOut = err && (err.name === 'AbortError' || String(err).includes('AbortError')); container.innerHTML = '<div style="text-align:center;color:var(--text-secondary);padding:20px;">Failed to calculate passes</div>';
container.innerHTML = `<div style="text-align:center;color:var(--text-secondary);padding:20px;">${timedOut ? 'Timed out calculating passes' : 'Failed to calculate passes'}</div>`;
} else { } else {
renderPassList(); renderPassList();
} }