L13 Planung: Geocoding der Objekte über OpenStreetMap Nominatim
Provider-Interface (nominatim|none), strukturierte Suche mit User-Agent und Accept-Language, Drosselung 1/s je Prozess, Job geocode-site (Worker: Concurrency 1 + Limiter), Cache am Objekt, manuelle Koordinaten bleiben, Auslöser Anlage/Adressänderung/Import-Bestätigung nur per Queue, Backfill-Skript, Env-Beispiele. Tests mit Fake-Provider, Nominatim nie aufgerufen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Minimum-interval limiter: callers are released one after another with at least `intervalMs`
|
||||
* between two slots (Nominatim policy: max. 1 request per second). Clock is injectable for tests.
|
||||
*/
|
||||
export type Clock = { now: () => number; sleep: (ms: number) => Promise<void> };
|
||||
|
||||
const realClock: Clock = { now: () => Date.now(), sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)) };
|
||||
|
||||
export function createIntervalLimiter(intervalMs: number, clock: Clock = realClock) {
|
||||
let next = 0;
|
||||
return {
|
||||
/** Waits for the next free slot and returns its timestamp. */
|
||||
async acquire(): Promise<number> {
|
||||
const now = clock.now();
|
||||
const slot = Math.max(now, next);
|
||||
next = slot + intervalMs;
|
||||
if (slot > now) await clock.sleep(slot - now);
|
||||
return slot;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** Process-wide limiter for all Nominatim requests of this process (worker, backfill script). */
|
||||
export const nominatimLimiter = createIntervalLimiter(1_000);
|
||||
Reference in New Issue
Block a user