info-canicule/scripts/check-mf-loadbalancer.mjs
Florian 8a89dbbac1 chore(scripts): diagnostic load-balancer MF (DPVigilance update_time)
Script ad-hoc pour mesurer la désynchro WSO2 du gateway MF. Tabule les
update_time distincts sur N fetches séquentiels et conclut si la mitigation
MF_PARALLEL_FETCHES=3 reste justifiée. Constaté 2026-05-26 :
~60/40 split entre 2 update_time → à revérifier périodiquement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 18:58:10 +02:00

57 lines
2.3 KiB
JavaScript

#!/usr/bin/env node
// Diagnostic ad-hoc : le gateway Météo France (WSO2) load-balance entre plusieurs
// instances qui peuvent être désynchronisées sur /DPVigilance/v1/cartevigilance/encours.
// Constaté 2026-05-26 (cf. vigilance.ts:84-89). Ce script déclenche N fetches
// séquentiels et tabule les `update_time` distincts pour décider si le hack
// MF_PARALLEL_FETCHES=3 est toujours nécessaire.
//
// Usage : METEOFRANCE_API_KEY=xxx node scripts/check-mf-loadbalancer.mjs [N=20]
const KEY = process.env.METEOFRANCE_API_KEY;
if (!KEY) {
console.error('METEOFRANCE_API_KEY required');
process.exit(1);
}
const N = parseInt(process.argv[2] ?? '20', 10);
const URL = 'https://public-api.meteofrance.fr/public/DPVigilance/v1/cartevigilance/encours';
const counts = new Map();
const failures = [];
const start = Date.now();
for (let i = 0; i < N; i++) {
try {
const res = await fetch(URL, { headers: { apikey: KEY, Accept: 'application/json' } });
if (!res.ok) {
failures.push(`#${i}: HTTP ${res.status}`);
continue;
}
const j = await res.json();
const t = j?.product?.update_time ?? '<missing>';
counts.set(t, (counts.get(t) ?? 0) + 1);
process.stdout.write(`${i + 1}/${N}${t}\n`);
} catch (e) {
failures.push(`#${i}: ${e.message}`);
}
}
const elapsed = ((Date.now() - start) / 1000).toFixed(1);
console.log(`\n=== Résumé (${N} fetches en ${elapsed}s) ===`);
const sorted = [...counts.entries()].sort((a, b) => (a[0] < b[0] ? 1 : -1));
for (const [t, c] of sorted) {
const bar = '█'.repeat(Math.round((c / N) * 40));
console.log(`${t} ${c.toString().padStart(3)}/${N} ${bar}`);
}
if (failures.length) {
console.log(`\nÉchecs: ${failures.length}`);
for (const f of failures) console.log(' ' + f);
}
console.log(`\nDistinct update_time: ${counts.size}`);
if (counts.size === 1) {
console.log('→ Pas de désynchro détectée sur cet échantillon. Tu peux probablement réduire MF_PARALLEL_FETCHES à 1.');
} else {
const newest = sorted[0]?.[0];
const newestCount = sorted[0]?.[1] ?? 0;
console.log(`→ Désynchro confirmée. Le bulletin le plus récent est ${newest} (${newestCount}/${N} = ${Math.round(newestCount/N*100)}%).`);
console.log(' Mitigation actuelle (MF_PARALLEL_FETCHES=3 + sort par update_time desc) reste justifiée.');
}