Données en retard : choisir ce que chaque opération peut accepter
Une donnée absente ou ancienne ne bloque pas tous les usages. Choisir, opération par opération, quand attendre, limiter le service ou accepter un retard.
Article
Dans un monolithe, un traitement différé peut laisser deux modules en décalage. Quand faut-il attendre une réponse et comment gérer une mise à jour tardive ?
Un client vient de s'inscrire, mais le module de facturation ne le connaît pas encore. Les deux modules tournent pourtant dans la même application. Si l'inscription transmet ses changements par un traitement différé, ce décalage est possible. Le choix entre échange synchrone et asynchrone doit tenir compte de ce qui peut attendre.
Un appel synchrone attend la réponse avant de continuer. Le module de facturation peut, par exemple, demander directement une information au module d'inscription.
Un échange asynchrone laisse le destinataire traiter la demande plus tard. L'inscription publie « client créé » ; la facturation l'apprend lorsque son consommateur traite cet événement.
Le premier choix relie les temps de réponse des deux modules. Le second permet de les traiter séparément, mais crée des états intermédiaires qu'il faut prévoir.
Un appel entre objets du même processus évite le transport réseau. Son travail peut néanmoins prendre du temps : accès au disque, requête de base de données ou attente d'un verrou.
Attendre la réponse ne garantit pas non plus que les données seront encore identiques une fois l'appel terminé. Une autre opération peut les modifier. Pour protéger une règle métier, il faut une transaction et une gestion de la concurrence adaptées.
Le synchrone convient lorsque la réponse est nécessaire pour poursuivre et que cette dépendance reste acceptable. L'asynchrone convient lorsque le travail peut être différé, absorbé par une file ou repris indépendamment.
L'inscription enregistre le nouveau client à 10 h 00. L'événement est traité par la facturation un peu plus tard. Une demande de facture qui arrive entre les deux peut ne pas trouver le client dans la copie locale.
Ce n'est pas nécessairement une panne : c'est une conséquence possible du fonctionnement choisi. Le délai peut toutefois devenir anormal si le consommateur est arrêté ou si un message échoue sans être repris.
La même situation se rencontre avec une projection de lecture, un index de recherche ou un processus en plusieurs étapes.
| Réponse possible | Quand elle convient |
|---|---|
| Signaler que les données ne sont pas encore disponibles | L'opération ne peut pas continuer et l'appelant peut revenir plus tard. |
| Attendre ou réessayer pendant un délai limité | Le décalage est habituellement court et l'attente reste acceptable. |
| Enregistrer une demande en attente | Le métier autorise un traitement différé clairement identifié. |
Évitez de confondre « client inexistant » avec « client peut-être pas encore synchronisé ». Le message donné à l'utilisateur et la reprise attendue peuvent être très différents.
Les tentatives doivent être limitées et espacées. Sans cela, elles peuvent surcharger le composant qui essaie déjà de rattraper son retard.
Le théorème CAP traite des garanties possibles pendant une partition réseau. Un travail placé dans une file du même processus n'est pas, à lui seul, une partition.
Il existe néanmoins un arbitrage entre fraîcheur des données, temps de réponse et coordination. Le cadre PACELC examine notamment les compromis entre latence et cohérence hors partition. Pour nos modules, le point utile est surtout de définir le retard accepté et la façon de le rattraper.
Un bus est un intermédiaire qui achemine les messages. Son nom ne dit pas si les messages survivent à un redémarrage, arrivent dans l'ordre ou peuvent être livrés plusieurs fois.
Une file uniquement en mémoire peut perdre le travail en attente si le processus s'arrête. Une file durable avec reprises peut livrer des doublons. Le destinataire doit alors être idempotent : une répétition ne doit pas produire un effet métier supplémentaire.
Si le changement local et sa diffusion doivent rester liés, une outbox peut enregistrer l'intention d'envoi dans la même transaction. Elle ne supprime pas le besoin de surveiller la livraison et le traitement.
Suivez l'âge du travail en attente et les erreurs persistantes. Un identifiant commun permet de retrouver une opération dans les traces de plusieurs modules, ou de plusieurs instances du monolithe.
Prévoyez aussi la réconciliation des copies si une mise à jour a été manquée. Le choix de l'asynchrone devient exploitable lorsque cette reprise est connue et testable.
Si une règle exige en permanence une coordination très étroite entre deux modules, examinez leur frontière. La déplacer peut simplifier le système. Si elle reste pertinente, rendez le mécanisme de coordination explicite au lieu de supposer que la proximité du code suffit.
Explorer
Choisis dans l’index d’après les étiquettes de cet article — les plus proches d’abord, hors de sa série. Rien n’est écrit à la main : un article publié demain avec les mêmes étiquettes y prendra place.
Une donnée absente ou ancienne ne bloque pas tous les usages. Choisir, opération par opération, quand attendre, limiter le service ou accepter un retard.
Une commande validée peut manquer quelques instants dans une liste, même dans un monolithe. Voici d’où vient ce délai et comment le rendre compréhensible.
Une commande expédiée met à jour une liste et déclenche un courriel. Ces effets ne se réparent pas de la même façon : voici comment organiser leur reprise.
Laisser un commentaire
Votre commentaire sera relu avant d'être publié.