perf: skip previous-1950-2024 fetch si latest suffit (cold-fetch -90%)
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Some checks are pending
Deploy info-canicule / deploy (push) Waiting to run
Latest fichier (~50 KB compressé) couvre l'année courante et la précédente. En mai 2026 il contient janvier 2025 → présent (~17 mois > 365j requis). Previous (~4 MB compressé) n'est nécessaire que si latest a < 365j — ce qui ne se produit qu'en début d'année (jan-mar 2025 par exemple). Cold-fetch dept : - Avant : ~17s (latest + previous + parsing 70 ans de data inutiles) - Après : ~2-3s (latest seul, parse de quelques mois) + mem_limit 256m → 512m pour donner du headroom au cold-fetch concurrent (constaté : 5 workers warmup parallèles ont OOM le container). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b342ea7375
commit
ac46637377
2 changed files with 32 additions and 20 deletions
|
|
@ -17,8 +17,8 @@ services:
|
||||||
- HOST=0.0.0.0
|
- HOST=0.0.0.0
|
||||||
networks:
|
networks:
|
||||||
- shared-net
|
- shared-net
|
||||||
mem_limit: 256m
|
mem_limit: 512m
|
||||||
cpus: 0.5
|
cpus: 1.0
|
||||||
logging:
|
logging:
|
||||||
driver: json-file
|
driver: json-file
|
||||||
options:
|
options:
|
||||||
|
|
|
||||||
|
|
@ -83,23 +83,8 @@ async function fetchOne(url: string): Promise<string | null> {
|
||||||
return gunzipSync(buf).toString('utf-8');
|
return gunzipSync(buf).toString('utf-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchClimato(dept: string): Promise<ClimatoSeries> {
|
function aggregateDays(byDate: Map<string, Agg>): DayObservation[] {
|
||||||
const byDate = new Map<string, Agg>();
|
return [...byDate.entries()]
|
||||||
// 1) latest (rapide, ~50 KB compressé) — couvre l'année courante
|
|
||||||
const latestUrl = buildUrl(dept, LATEST);
|
|
||||||
if (latestUrl) {
|
|
||||||
const text = await fetchOne(latestUrl);
|
|
||||||
if (text) parseCsvInto(text, byDate);
|
|
||||||
}
|
|
||||||
// 2) previous (~4 MB compressé) — nécessaire pour combler les jours hors année courante
|
|
||||||
// On le fetch toujours, son taille est tolérable au cold-fetch (cache 24h).
|
|
||||||
const previousUrl = buildUrl(dept, PREVIOUS);
|
|
||||||
if (previousUrl) {
|
|
||||||
const text = await fetchOne(previousUrl);
|
|
||||||
if (text) parseCsvInto(text, byDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
const days: DayObservation[] = [...byDate.entries()]
|
|
||||||
.sort(([a], [b]) => (a < b ? -1 : 1))
|
.sort(([a], [b]) => (a < b ? -1 : 1))
|
||||||
.map(([date, agg]) => ({
|
.map(([date, agg]) => ({
|
||||||
date,
|
date,
|
||||||
|
|
@ -109,8 +94,35 @@ async function fetchClimato(dept: string): Promise<ClimatoSeries> {
|
||||||
rr: agg.rrN > 0 ? +(agg.rrSum / agg.rrN).toFixed(1) : null,
|
rr: agg.rrN > 0 ? +(agg.rrSum / agg.rrN).toFixed(1) : null,
|
||||||
stations: agg.stations,
|
stations: agg.stations,
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchClimato(dept: string): Promise<ClimatoSeries> {
|
||||||
|
const byDate = new Map<string, Agg>();
|
||||||
|
// 1) latest (~50 KB compressé) — couvre l'année courante.
|
||||||
|
// Le fichier latest-2025-2026 contient janvier 2025 → aujourd'hui.
|
||||||
|
// En 2026, ça couvre déjà > 365 jours, donc previous n'est pas nécessaire.
|
||||||
|
const latestUrl = buildUrl(dept, LATEST);
|
||||||
|
if (latestUrl) {
|
||||||
|
const text = await fetchOne(latestUrl);
|
||||||
|
if (text) parseCsvInto(text, byDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
let days = aggregateDays(byDate);
|
||||||
|
|
||||||
|
// 2) previous (~4 MB compressé) — UNIQUEMENT si latest ne couvre pas MAX_DAYS.
|
||||||
|
// Cas où c'est nécessaire : début 2025 (latest n'a que ~quelques mois).
|
||||||
|
// En mai 2026, latest couvre déjà ~17 mois → previous skip → cold-fetch ~10× plus rapide.
|
||||||
|
if (days.length < MAX_DAYS) {
|
||||||
|
const previousUrl = buildUrl(dept, PREVIOUS);
|
||||||
|
if (previousUrl) {
|
||||||
|
const text = await fetchOne(previousUrl);
|
||||||
|
if (text) {
|
||||||
|
parseCsvInto(text, byDate);
|
||||||
|
days = aggregateDays(byDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Garder MAX_DAYS derniers jours (365)
|
|
||||||
return { dept, fetchedAt: new Date().toISOString(), days: days.slice(-MAX_DAYS) };
|
return { dept, fetchedAt: new Date().toISOString(), days: days.slice(-MAX_DAYS) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue