Article

CQRS : comprendre et gérer le retard des vues de lecture

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.

Vous créez une commande, obtenez une confirmation, puis ouvrez la liste : elle n'y figure pas encore. Si cette liste est mise à jour en différé, quelques instants peuvent séparer l'enregistrement et son affichage. Ce délai peut être prévu. Il faut toutefois le distinguer d'une panne et expliquer à l'utilisateur ce qui se passe.

Deux étapes peuvent se terminer à des moments différents

Le modèle de commande valide et enregistre la décision. Le modèle de lecture prépare la réponse attendue par l'écran. Lorsque sa mise à jour est asynchrone, elle s'exécute après la première étape.

Le délai dépend de la file d'attente, du traitement de projection et de ses éventuelles reprises. Une séparation entre deux bases n'est pas indispensable : deux traitements utilisant la même base peuvent aussi s'exécuter à des moments différents.

Le write model, fortement cohérent, et le read model, éventuellement cohérent, séparés par une frontière que la projection traverse avec un délai variable.
La cohérence forte se concentre là où la décision se prend. La projection la propage vers un read model qui peut, un instant, être en retard.

Un monolithe peut lui aussi avoir des lectures en retard

Imaginez un module qui publie un événement après avoir enregistré une commande. Un autre module le traite dans un fil d'exécution distinct pour actualiser la liste. Entre les deux, la liste présente l'ancien état.

Tout se déroule dans la même application. Il n'y a pas nécessairement de réseau, mais il y a bien une reprise à organiser si le processus s'arrête avant la mise à jour.

Cette situation partage certaines difficultés avec les systèmes distribués : retard, répétition et perte d'un travail à effectuer. Elle ne transforme pas pour autant chaque appel interne en partition réseau.

CQRS permet aussi une mise à jour dans la même transaction

Si les deux modèles partagent un stockage adapté, la décision et la vue peuvent être mises à jour ensemble. La transaction locale rend alors les deux changements visibles à sa validation, sous réserve du chemin de lecture utilisé, notamment des caches ou répliques.

Une mise à jour différée réduit le travail imposé à cette transaction et permet de traiter les vues séparément. Elle ajoute un délai et une obligation de suivi.

BesoinApproche possible
Confirmer une décision immédiatementRenvoyer un accusé fondé sur la décision enregistrée.
Lire une petite vue sans retard de projectionLa mettre à jour dans la même transaction si le stockage le permet.
Alimenter un index de recherche coûteuxLe mettre à jour en différé avec un retard mesuré.

Il n'est donc pas nécessaire de choisir un seul niveau de fraîcheur pour toute l'application. La décision dépend de l'usage et de ses conséquences.

Un délai normal n'est pas une partition réseau

Le théorème CAP décrit un arbitrage en présence d'une partition réseau : on ne peut garantir à la fois la cohérence forte et la disponibilité au sens du théorème. Il ne suffit pas à expliquer toute lecture en retard.

Une projection qui attend normalement son tour relève d'abord du choix de mise à jour asynchrone. L'arbitrage entre rapidité et cohérence en fonctionnement normal est notamment discuté dans le cadre PACELC, proposé par Daniel Abadi.

Pour exploiter l'application, la question pratique reste la même : quel retard est acceptable, comment le mesure-t-on et que fait-on lorsqu'il devient trop grand ? Le nom du modèle théorique ne remplace pas ces réponses.

Donner une réponse claire après une écriture

Après la création d'une commande, affichez son identifiant et la confirmation de son enregistrement. Ne demandez pas à l'utilisateur de déduire la réussite uniquement de sa présence dans une liste éventuellement en retard.

Si le parcours exige une relecture immédiate, plusieurs solutions existent : lire l'état de référence, attendre que la projection atteigne la version attendue ou signaler explicitement l'actualisation en cours. L'attente doit être bornée et déboucher sur un message utile si elle échoue.

Une commande absente après une seconde peut correspondre au délai normal. Une commande toujours absente après dix minutes peut signaler un problème. Ce sont les engagements du service et ses mesures qui permettent de distinguer les deux.

Surveiller la propagation comme un traitement à part entière

Suivez l'âge des mises à jour en attente, les erreurs et la dernière version appliquée. Prévoyez une reprise après interruption et une reconstruction si la projection devient incohérente.

Le système peut ainsi accepter un délai sans laisser les écarts s'accumuler silencieusement. L'article suivant aborde un autre problème : coordonner plusieurs décisions qui ne partagent pas de transaction.

Sources

Explorer

Sur le même sujet

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.

Laisser un commentaire

Elle n'est jamais affichée ni publiée. Elle sert à regrouper vos commentaires et, si vous vous inscrivez un jour avec elle, à vous les rendre.

Votre commentaire sera relu avant d'être publié.