fix(phase26): revert batch geocode, use rate-limited concurrent requests to avoid server freeze
This commit is contained in:
+25
-21
@@ -36,10 +36,17 @@
|
|||||||
let _geoCache = {}; // key → label, pre-populated on trip load
|
let _geoCache = {}; // key → label, pre-populated on trip load
|
||||||
|
|
||||||
function _geoKey(lat, lon) {
|
function _geoKey(lat, lon) {
|
||||||
return `${lat.toFixed(3)},${lon.toFixed(3)}`;
|
const la = typeof lat === 'number' ? lat : parseFloat(lat);
|
||||||
|
const lo = typeof lon === 'number' ? lon : parseFloat(lon);
|
||||||
|
if (isNaN(la) || isNaN(lo)) return null;
|
||||||
|
return `${la.toFixed(3)},${lo.toFixed(3)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function preloadGeocodes(points) {
|
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.
|
||||||
_geoCache = {};
|
_geoCache = {};
|
||||||
const seen = new Set();
|
const seen = new Set();
|
||||||
const queue = [];
|
const queue = [];
|
||||||
@@ -51,30 +58,27 @@
|
|||||||
}
|
}
|
||||||
if (!queue.length) return;
|
if (!queue.length) return;
|
||||||
|
|
||||||
// Try batch endpoint first (server has it, Pi falls back to 404)
|
const CONCURRENCY = 2;
|
||||||
const coords = queue.map(q => ({lat: q.lat, lon: q.lon}));
|
let idx = 0;
|
||||||
const ctrl = new AbortController();
|
function next() {
|
||||||
const t = setTimeout(() => ctrl.abort(), 15000);
|
if (idx >= queue.length) return;
|
||||||
fetch('/api/geocode/batch', {
|
const item = queue[idx++];
|
||||||
method: 'POST',
|
const ctrl = new AbortController();
|
||||||
headers: {'Content-Type': 'application/json'},
|
const t = setTimeout(() => ctrl.abort(), 3000);
|
||||||
body: JSON.stringify({coords: coords}),
|
fetch(`/api/geocode?lat=${item.lat}&lon=${item.lon}`, { signal: ctrl.signal })
|
||||||
signal: ctrl.signal,
|
.then(r => { clearTimeout(t); return r.ok ? r.json() : null; })
|
||||||
})
|
.then(data => {
|
||||||
.then(r => { clearTimeout(t); return r.ok ? r.json() : null; })
|
_geoCache[item.key] = (data && data.label) || null;
|
||||||
.then(data => {
|
})
|
||||||
if (data) {
|
.catch(() => { clearTimeout(t); })
|
||||||
for (const q of queue) {
|
.finally(() => next());
|
||||||
if (data[q.key]) _geoCache[q.key] = data[q.key];
|
}
|
||||||
}
|
for (let i = 0; i < CONCURRENCY && i < queue.length; i++) next();
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => { clearTimeout(t); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function geocodePoint(lat, lon) {
|
function geocodePoint(lat, lon) {
|
||||||
const key = _geoKey(lat, lon);
|
const key = _geoKey(lat, lon);
|
||||||
if (key === _lastGeoKey) return;
|
if (!key || key === _lastGeoKey) return;
|
||||||
_lastGeoKey = key;
|
_lastGeoKey = key;
|
||||||
const fallback = `${lat.toFixed(5)}, ${lon.toFixed(5)}`;
|
const fallback = `${lat.toFixed(5)}, ${lon.toFixed(5)}`;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user