L’architecture qui tient quand les sources ne tiennent pas
Séparer orchestration, acquisition et normalisation
Le premier principe de robustesse est la séparation des responsabilités. Une architecture saine distingue au minimum trois couches.
Orchestration. Elle décide quand lancer un connecteur, avec quelle priorité, quelle fenêtre de rattrapage et quelles dépendances. C’est là qu’on gère les calendriers, les backfills, les quotas globaux et l’ordonnancement.
Acquisition. Elle parle à la source. Elle télécharge, interroge, pagine, reprend, stocke le brut, calcule des empreintes, et annote la réponse avec des métadonnées techniques, code HTTP, taille, hash, horodatage, latence, version du connecteur.
Normalisation. Elle transforme le brut en enregistrement exploitable. C’est ici que l’on mappe les champs, résout les encodages, nettoie les identifiants, traite les dates, et rattache les pièces à une taxonomie interne.
Pourquoi cette séparation compte-t-elle ? Parce qu’elle permet des garanties différentes. L’acquisition peut être strictement idempotente au niveau du blob brut. La normalisation peut évoluer avec versioning sans nécessiter de re-télécharger la source. L’orchestrateur peut relancer un lot sans supposer quoi que ce soit sur le parseur.
Une architecture où le même script “fait tout” fonctionne jusqu’au jour où il faut rejouer six semaines d’historique après une correction de mapping. Ce jour-là, elle devient un roman de gare.
Le stockage brut n’est pas un luxe, c’est votre police d’assurance
Conserver la réponse brute, HTML, XML, JSON, CSV, PDF, archive ZIP, n’est pas une coquetterie d’ingénieur. C’est la condition pour auditer, rejouer et comparer. Sans stockage brut, toute correction devient spéculative. Vous ne savez pas si l’erreur vient de la source, du connecteur, du parseur, ou d’une hypothèse métier devenue fausse.
Le stockage brut permet aussi de gérer les corrections silencieuses. Si l’URL est identique mais que le contenu change, un hash de contenu vous le dira. Si le contenu est identique mais que les métadonnées changent, vous pourrez décider si cela justifie une nouvelle normalisation. Dans les deux cas, vous sortez du monde fragile du “je pense que c’est le même document”.
Les connecteurs doivent être petits, opinionnés, remplaçables
Chaque régulateur mérite son connecteur, même si plusieurs semblent similaires. La tentation de l’abstraction générale arrive vite. Elle est parfois utile, rarement au début. Les sources divergent dans les détails, et les détails sont précisément l’endroit où les collectes meurent.
Un bon connecteur fait peu de choses, mais les fait explicitement. Il sait comment lister les nouveaux objets, comment reprendre après erreur, comment détecter les doublons, comment identifier une correction, et quelles hypothèses il fait sur la source. Il expose aussi sa version. Quand un changement de site survient, vous voulez pouvoir dire, “la version 12 du connecteur AMF a commencé à rater le champ X à 08:42 UTC”. Pas “quelque chose a bougé quelque part”.
Retries, backoff et rattrapage, l’art d’échouer proprement
Tous les retries ne se valent pas
Le retry naïf est l’une des manières les plus efficaces de transformer une petite panne en gros problème. Rejouer immédiatement, sans distinction de cause, peut saturer la source, aggraver un rate limit, ou multiplier les téléchargements redondants. Il faut donc classer les erreurs.
Les erreurs transitoires, timeout réseau, 502, 503, reset de connexion, se prêtent à un retry avec backoff exponentiel et jitter. Les erreurs structurelles, 404 persistant sur une route attendue, changement de schéma, parse failure déterministe, doivent plutôt ouvrir un incident et geler certaines tentatives automatiques. Les erreurs ambiguës, 200 OK avec contenu vide, méritent souvent une vérification secondaire, par exemple comparaison avec le volume historique attendu, contrôle d’un autre endpoint, ou relecture différée.
Le point important est simple, un retry est une hypothèse sur la nature de l’échec. Si l’hypothèse est mauvaise, l’automatisation devient une machine à bruit.
Le backoff doit respecter la source, pas seulement votre SLA
Dans les systèmes de marché, on parle volontiers de latence. Dans la collecte réglementaire, la vertu est parfois la patience. Les régulateurs ne sont pas des API de trading. Ils n’ont ni les mêmes budgets d’infrastructure, ni les mêmes priorités, ni la même tolérance aux accès agressifs.
Un backoff bien conçu tient compte des signaux de la source, en-têtes Retry-After, schémas de rate limiting, heures de maintenance connues, et comportement observé. Il tient aussi compte du coût d’un retard. Rater une publication pendant cinq minutes n’a pas la même gravité que la manquer pendant cinq heures. Il faut donc arbitrer entre courtoisie technique et fenêtre d’angle mort acceptable.
Le rattrapage doit être une fonction native, pas une improvisation
Tout système de collecte finit par avoir besoin de backfills. Panne d’un connecteur, correction d’un parseur, ajout d’un champ métier, migration de stockage, peu importe. Si le rattrapage n’est pas prévu dès le départ, il devient dangereux.
Une bonne architecture permet de rejouer une plage temporelle, ou un ensemble d’identifiants, sans casser l’état courant. Elle sait distinguer “re-télécharger”, “re-parser”, “re-normaliser” et “re-publier”. Elle sait aussi limiter l’impact, par exemple en traitant d’abord les journées récentes, puis l’historique profond. Sans cela, le backfill devient un mélange de scripts ad hoc, de SQL nerveux et de prières discrètes.