fix(phase26): abort preload fetches when switching trips to prevent server freeze
This commit is contained in:
+12
-9
@@ -33,7 +33,8 @@
|
||||
|
||||
let _geoTimer = null;
|
||||
let _lastGeoKey = null;
|
||||
let _geoCache = {}; // key → label, pre-populated on trip load
|
||||
let _geoCache = {};
|
||||
let _preloadController = null;
|
||||
|
||||
function _geoKey(lat, lon) {
|
||||
const la = typeof lat === 'number' ? lat : parseFloat(lat);
|
||||
@@ -43,16 +44,17 @@
|
||||
}
|
||||
|
||||
function preloadGeocodes(points) {
|
||||
// Pre-fetch geocode labels for all unique coordinates with a small
|
||||
// concurrency cap so the server (which uses slow Nominatim) doesn't
|
||||
// get overwhelmed. The Pi's reverse_geocoder is instant, so this
|
||||
// still works fast there.
|
||||
// Abort any in-flight preload from a previous trip selection.
|
||||
if (_preloadController) _preloadController.abort();
|
||||
_preloadController = new AbortController();
|
||||
const signal = _preloadController.signal;
|
||||
|
||||
_geoCache = {};
|
||||
const seen = new Set();
|
||||
const queue = [];
|
||||
for (const p of points) {
|
||||
const key = _geoKey(p.latitude, p.longitude);
|
||||
if (seen.has(key)) continue;
|
||||
if (!key || seen.has(key)) continue;
|
||||
seen.add(key);
|
||||
queue.push({ key, lat: p.latitude, lon: p.longitude });
|
||||
}
|
||||
@@ -61,17 +63,18 @@
|
||||
const CONCURRENCY = 2;
|
||||
let idx = 0;
|
||||
function next() {
|
||||
if (idx >= queue.length) return;
|
||||
if (idx >= queue.length || signal.aborted) return;
|
||||
const item = queue[idx++];
|
||||
const ctrl = new AbortController();
|
||||
const t = setTimeout(() => ctrl.abort(), 3000);
|
||||
signal.addEventListener('abort', () => ctrl.abort());
|
||||
fetch(`/api/geocode?lat=${item.lat}&lon=${item.lon}`, { signal: ctrl.signal })
|
||||
.then(r => { clearTimeout(t); return r.ok ? r.json() : null; })
|
||||
.then(data => {
|
||||
_geoCache[item.key] = (data && data.label) || null;
|
||||
if (!signal.aborted) _geoCache[item.key] = (data && data.label) || null;
|
||||
})
|
||||
.catch(() => { clearTimeout(t); })
|
||||
.finally(() => next());
|
||||
.finally(() => { if (!signal.aborted) next(); });
|
||||
}
|
||||
for (let i = 0; i < CONCURRENCY && i < queue.length; i++) next();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user