fix(osm): end the server's place search before the voice answer gives up

The voice answer waited 25 s for /api/osm/features, while the server let
Overpass run for 25 s and itself waited up to 40 s per endpoint and 45 s
in all. When the browser gave up first it closed the request, the route
cancelled the upstream query, and nothing was cached, so the OSM_TIMEOUT
retry started the same query from scratch and timed out again.

The server now tells Overpass 20 s, waits 22 s per endpoint and 22 s in
all, which ends inside the client's 25 s. A test pins that ordering.
This commit is contained in:
Sameh Khamis committed 2026-11-03 09:08:16 -08:00
1 parent 51637a5e96
commit 4efba8ccca
5 files changed
+37 -10

No files matched your search

+18 -1
View File
@@ -18,6 +18,23 @@ import {
} from '../../server/providers/overpass/osmFeatures.js';
import { installOsmFeaturesRoute } from '../../server/providers/overpass/osmFeaturesRoute.js';
import { sanitizeOverpassBody } from '../../server/providers/overpass/query.js';
import { OSM_QUERY_LIMITS } from '../voice/osmActions.js';
test('the server finishes its whole search before the voice answer gives up', () => {
// When the browser stops waiting, the route aborts the upstream query, so
// an OSM_TIMEOUT retry could never be served from the cache.
assert.ok(
OSM_FEATURE_LIMITS.timeoutS * 1000 < OSM_FEATURE_LIMITS.upstreamTimeoutMs,
'Overpass gives up before the server stops waiting for it',
);
assert.ok(
OSM_FEATURE_LIMITS.upstreamTimeoutMs <= OSM_FEATURE_LIMITS.upstreamBudgetMs,
);
assert.ok(
OSM_FEATURE_LIMITS.upstreamBudgetMs + 2_000 <= OSM_QUERY_LIMITS.budgetMs,
`server budget ${OSM_FEATURE_LIMITS.upstreamBudgetMs} ms must end before the client's ${OSM_QUERY_LIMITS.budgetMs} ms`,
);
});
test('a preset and a small box compile to a bounded query', () => {
const compiled = compileOsmFeatureQuery({
@@ -28,7 +45,7 @@ test('a preset and a small box compile to a bounded query', () => {
assert.equal(compiled.ok, true);
assert.equal(
compiled.ql,
'[out:json][timeout:25][maxsize:67108864];(nwr["amenity"="hospital"](27.6,85.2,27.8,85.4););out center tags 50;',
'[out:json][timeout:20][maxsize:67108864];(nwr["amenity"="hospital"](27.6,85.2,27.8,85.4););out center tags 50;',
);
assert.doesNotMatch(compiled.ql, /area/, 'no boundary-area scan');
const count = compileOsmFeatureQuery({
+5 -1
View File
@@ -34,7 +34,11 @@ export const OSM_QUERY_LIMITS = Object.freeze({
maxCountDeg2: 36,
defaultLimit: 500,
maxLimit: 1000,
/** The answer waits this long before cancelling its provider request. */
/**
* The answer waits this long before cancelling its provider request. It
* must outlast the server's whole search (`OSM_FEATURE_LIMITS.upstreamBudgetMs`,
* 22 s), or the cancelled search caches nothing for the retry.
*/
budgetMs: 25_000,
});