add additional timeout for entire request

This commit is contained in:
Sarah Hoffmann 2023-08-25 09:16:53 +02:00
parent 161d17d85b
commit 1115705cbc
3 changed files with 23 additions and 5 deletions

View File

@ -194,7 +194,9 @@ class NominatimAPIAsync:
async with self.begin() as conn: async with self.begin() as conn:
conn.set_query_timeout(self.query_timeout) conn.set_query_timeout(self.query_timeout)
geocoder = ForwardGeocoder(conn, ntyp.SearchDetails.from_kwargs(params)) geocoder = ForwardGeocoder(conn, ntyp.SearchDetails.from_kwargs(params),
self.config.get_int('REQUEST_TIMEOUT') \
if self.config.REQUEST_TIMEOUT else None)
phrases = [Phrase(PhraseType.NONE, p.strip()) for p in query.split(',')] phrases = [Phrase(PhraseType.NONE, p.strip()) for p in query.split(',')]
return await geocoder.lookup(phrases) return await geocoder.lookup(phrases)
@ -252,7 +254,9 @@ class NominatimAPIAsync:
if amenity: if amenity:
details.layers |= ntyp.DataLayer.POI details.layers |= ntyp.DataLayer.POI
geocoder = ForwardGeocoder(conn, details) geocoder = ForwardGeocoder(conn, details,
self.config.get_int('REQUEST_TIMEOUT') \
if self.config.REQUEST_TIMEOUT else None)
return await geocoder.lookup(phrases) return await geocoder.lookup(phrases)
@ -276,7 +280,9 @@ class NominatimAPIAsync:
if details.keywords: if details.keywords:
await make_query_analyzer(conn) await make_query_analyzer(conn)
geocoder = ForwardGeocoder(conn, details) geocoder = ForwardGeocoder(conn, details,
self.config.get_int('REQUEST_TIMEOUT') \
if self.config.REQUEST_TIMEOUT else None)
return await geocoder.lookup_pois(categories, phrases) return await geocoder.lookup_pois(categories, phrases)

View File

@ -9,6 +9,7 @@ Public interface to the search code.
""" """
from typing import List, Any, Optional, Iterator, Tuple from typing import List, Any, Optional, Iterator, Tuple
import itertools import itertools
import datetime as dt
from nominatim.api.connection import SearchConnection from nominatim.api.connection import SearchConnection
from nominatim.api.types import SearchDetails from nominatim.api.types import SearchDetails
@ -24,9 +25,11 @@ class ForwardGeocoder:
""" Main class responsible for place search. """ Main class responsible for place search.
""" """
def __init__(self, conn: SearchConnection, params: SearchDetails) -> None: def __init__(self, conn: SearchConnection,
params: SearchDetails, timeout: Optional[int]) -> None:
self.conn = conn self.conn = conn
self.params = params self.params = params
self.timeout = dt.timedelta(seconds=timeout or 1000000)
self.query_analyzer: Optional[AbstractQueryAnalyzer] = None self.query_analyzer: Optional[AbstractQueryAnalyzer] = None
@ -71,6 +74,7 @@ class ForwardGeocoder:
""" """
log().section('Execute database searches') log().section('Execute database searches')
results = SearchResults() results = SearchResults()
end_time = dt.datetime.now() + self.timeout
num_results = 0 num_results = 0
min_ranking = 1000.0 min_ranking = 1000.0
@ -85,6 +89,8 @@ class ForwardGeocoder:
log().result_dump('Results', ((r.accuracy, r) for r in results[num_results:])) log().result_dump('Results', ((r.accuracy, r) for r in results[num_results:]))
num_results = len(results) num_results = len(results)
prev_penalty = search.penalty prev_penalty = search.penalty
if dt.datetime.now() >= end_time:
break
if results: if results:
min_ranking = min(r.ranking for r in results) min_ranking = min(r.ranking for r in results)

View File

@ -215,8 +215,14 @@ NOMINATIM_SERVE_LEGACY_URLS=yes
NOMINATIM_API_POOL_SIZE=10 NOMINATIM_API_POOL_SIZE=10
# Timeout is seconds after which a single query to the database is cancelled. # Timeout is seconds after which a single query to the database is cancelled.
# The user receives a 503 response, when a query times out.
# When empty, then timeouts are disabled. # When empty, then timeouts are disabled.
NOMINATIM_QUERY_TIMEOUT=60 NOMINATIM_QUERY_TIMEOUT=10
# Maximum time a single request is allowed to take. When the timeout is
# exceeeded, the available results are returned.
# When empty, then timouts are disabled.
NOMINATIM_REQUEST_TIMEOUT=60
# Search elements just within countries # Search elements just within countries
# If, despite not finding a point within the static grid of countries, it # If, despite not finding a point within the static grid of countries, it