Comment faire le pont entre les systèmes avec état et les événements (et vaincre le gorille)

Vous avez un tout nouveau système CQRS, il est «complet» et vous êtes sur le point de commencer les tests d’intégration. Et le gorille de 800 livres qui dormait dans le coin pendant vos discussions de domaine se réveille.

Sans un seul coup d'œil sur vos diagrammes de domaine complets, vos user stories captivantes, vos maquettes d'interface utilisateur ou vos critères d'acceptation bien documentés, le processus se déroule au-delà de la «ligne de contour en pointillé» censée la retenir.

Les gorilles se déchaînent autour du bâtiment, détruisant les entités en ruines, réduisant la valeur en décombres, déracinant des agrégats et détruisant généralement tout consensus sur le projet. Gorilla, ton nom est Legacy Integration.

Salut les gars! Je suis impatient de voir comment votre application de micro-service RESTful s’intégrera à ce système ERP sur mesure vieux de trente ans! J'espère que vous aimez COBOL. (Image reproduite avec la permission de “Naruto” le macaque, qui n'est pas un gorille).

L’intégration de systèmes et de processus hérités peut constituer un projet parfaitement exécuté. C’est une migraine monstre d’un problème qui n’est enseigné qu’à l’école des coups durs. C’est également un problème auquel, en tant que développeur, vous devrez faire face (si vous ne l’avez pas déjà fait) lorsque vous commencez à travailler avec des entreprises et des domaines suffisamment établis.

Bien sûr, si vous êtes chanceux, vous n’avez pas encore commencé à coder - ou du moins, il est encore tôt dans le processus - lorsque le gorille se réveille. Ou, si vous êtes malin, vous voyez le gorille se cacher sous l’abat-jour dans le coin et, en frottant les cicatrices de votre dernière rencontre, vous prévenez son inévitable déchaînement en l’intégrant dès le début à votre architecture.

Faire face aux systèmes hérités

En tant que directeur adjoint de l’architecture au Bureau des systèmes d’information sur la recherche de UCLA, je suis chargé de combler de nombreuses lacunes en matière de systèmes et de données. UCLA possède un pipeline de plusieurs décennies de processus et de systèmes d’entreprise hérités de la recherche qui contrecarrent toute tentative de «perturber» ces approches traditionnelles avec les nouvelles technologies.

Ce qui est le plus inquiétant, c'est que ce pipeline est encombré de l'iceberg impénétrable occasionnel de données héritées qui nécessite souvent des discussions en temps réel.

Oh bon seigneur! Un data-berg! Non attendez, c'est juste un fatberg. Je suis heureux d’avoir opté pour une carrière dans le code au lieu de l’assainissement. (Crédit d'image: l'Associated Press)

À mon bureau, nous avons été chargés de fournir une intégration à ces systèmes existants à un rythme croissant. Nous développons également nos systèmes transactionnels sur mesure pour gérer les processus de petite entreprise.

Pour nos propres systèmes, nous suivons généralement le modèle de microservice. Nous intégrons davantage de complexité, comme la conception pilotée par le domaine (DDD) et l’approvisionnement en événements, le cas échéant. Notre principal défi pour ces systèmes est l'intégration héritée dans des systèmes à persistance d'état.

Approcher l'intégration

Je vais exposer notre approche dans les prochains paragraphes. C’est ainsi que nous avons abordé l’un des problèmes qui découlent du passage d’un système d’événement, en particulier d’un système d’événement hybride, à un système purement dirigé par l’État.

Un principe fondamental que les responsables de la mise en œuvre oublient souvent est que la sous-traitance d'événements ne doit pas être utilisée partout. C’est ce que dit Greg Young, qui est largement reconnu pour avoir introduit le modèle d’architecture logicielle «Event Sourcing».

Dans nos systèmes, nous utilisons l’approvisionnement en événements pour répondre à des exigences spécifiques. Parfois, nos applications ont un état pouvant résider en dehors du flux d'événements. De plus, certains de nos déclencheurs d'événements proviennent de changements d'état du système source peu fiables. Cela demanderait beaucoup de corrections d’événements post-hoc et de «rewind-replay» à corriger si nous ne devions dépendre que du flux d’événements.

Une solution sceptique

La solution que nous avons proposée à cet effet est celle que j'appelle «l'abonné sceptique». L'abonné sceptique s'attaque au problème du «manque de fiabilité» du côté des événements du système, du moins du point de vue de la machine à états héritée. Il s’adresse également aux systèmes qui risquent de manquer de générer des événements en raison de problèmes de données hérités externes:

  1. La source d'événements peut générer des événements qui n'entraînent pas de changements d'état pertinents pour la machine à états héritée. De son point de vue, ce sont des événements "faux positifs"
  2. La source d'événements peut ne pas générer les événements pour les changements d'état pertinents pour la machine à états héritée. De son point de vue, ce sont des événements "manqués" ou "sautés"
  3. Les événements peuvent ne pas être générés du tout à cause de bogues ou d'erreurs dans la source d'origine de l'événement. Cela se produit particulièrement dans les flux d'extraction-transformation-charge (ETL) des référentiels de données hérités. De toute perspective, ces événements sont véritablement «ignorés»

L’approche Skeptical Subscriber répond à ces préoccupations en restant méfiante vis-à-vis du flux d’événements. Il traite le flux d'événements comme un déclencheur possible ou une notification indiquant que l'état a changé, mais il accepte également d'autres déclencheurs possibles. Il ne croit pas non plus que les notifications de changement d'état sont correctes.

Une fois qu'il est informé que l'état peut avoir changé, l'abonné notifie une passerelle d'état qui interroge l'état du système généré par l'événement.

Cette passerelle d'état évalue l'état par rapport au dernier état connu (tel que le système souscripteur le savait).

Si la modification est pertinente, il met ensuite à jour l'état du système abonné et, si nécessaire, lance les processus métier du système abonné associés.

Mesdames et germes, l'abonné sceptique!

Quelques exigences

Pour utiliser cette approche, votre système d'abonnement doit:

  1. Persistez déjà, ou soyez capable de tirer de ce qui persiste, les attributs d'état dont il se soucie du système de sourcing d'événements
  2. Vous permet de refaire comment vous injectez des données de changement d'état

Votre système de sourcing d'événements doit:

  1. Fournir un service de requête qui représente de manière fiable l'état du système et inclut tous les attributs d'état requis par le système abonné
  2. Fournissez suffisamment de données dans le flux d'événements pour localiser les enregistrements pertinents dans le service de requête.
  3. Prendre en charge une "liste" ou une autre requête par lot à partir du service de requête

L'abonné sceptique que vous implémentez doit inclure:

  1. Passerelle d'état pouvant interroger le service d'interrogation sur un enregistrement particulier (piloté par un événement) ou sur une liste d'enregistrements (autre déclencheur permettant de rattraper les événements «manqués»)
  2. La passerelle d’état doit inclure une logique de comparaison de domaine à partir du contexte du système abonné qui élimine les enregistrements si, en ce qui concerne le domaine abonné, ils n’ont pas changé.
  3. Une implémentation d'abonnement aux événements pour appeler la passerelle par enregistrement à partir des événements
  4. Possibilité de mettre à jour la couche de persistance du système abonné avec les modifications (pour éviter la réactualisation du même enregistrement la prochaine fois), par exemple via un référentiel

L'abonné sceptique peut également mettre en œuvre le lancement de processus métier dans le système abonné.

Si cela dépend uniquement de l’état, cela peut être dû à la persistance de nouveaux enregistrements de processus pour lancer les processus concomitants. Sinon, il peut appeler n'importe quel API de processus exposé.

Si vous lancez ces processus, vous devez également mettre en œuvre le verrouillage de la passerelle afin de ne pas doubler l'initiation du processus si un déclencheur d'événement se produit pendant le processus ETL.

Résultats positifs

L'intégration de systèmes existants pose de nombreux autres problèmes, en particulier lorsque vous passez d'un contexte à un autre à un événement ou à un état. Toutefois, ce modèle nous aide à réduire le fardeau technique associé à la maintenance des événements lors de la consommation de données héritées (et incomplètes).

Avant de suivre ce modèle, nous utilisions une approche strictement événementielle. Nous avions perdu un accès rapide aux possibilités de support offertes par un état directement modifiable. Avec ce modèle, nous avons retrouvé ces opportunités. Lorsque le système existant se comporte mal parce qu’il ne «ressemble» pas aux événements qu’il reçoit, nous avons déplacé la tâche qui consiste à modifier le flux d’événements d’une manière ou d’une autre en une simple modification d’état.

Nous avons également ajouté une couche de couplage lâche pour isoler généralement le système abonné de l’exposition directe aux événements. Cela permet la redirection d'autres déclencheurs du système abonné.

Par exemple, un ETL hérité peut servir de déclencheur initial de passerelle d'état jusqu'à ce que vous soyez prêt à basculer vers un flux d'événements. Et nous l’avons fait sans trop compliquer le service CQRS en implémentant l’abonné sceptique interstitiel en tant qu’entité indépendante.

Voici un conseil pro pour les scientifiques de données et les ingénieurs qui les utilisent: si vous implémentez la persistance polyglotte dans le référentiel abonné, vous pouvez également créer un magasin de documents déjà filtré automatiquement aux modifications de données reflétant un processus métier significatif.

Enfin, dans le cas où un événement est «ignoré» ou «manqué», nous avons un chemin de soutien à la demande facile à suivre. Nous ré-informons l’abonné de cet enregistrement (si nous savons quel enregistrement a manqué un événement) ou nous effectuons une requête système «de rattrapage» (si nous n’en sommes pas sûr).

Nous pouvons le faire sans avoir à toucher le flux d'événements. Cela signifie que l'activité de support n'affectera pas les autres applications abonnées.

Dernières pensées

Ce n’est pas la solution idéale pour tous les problèmes (ni même pour la plupart des problèmes). Mais c’est une excellente solution pour tirer parti du couplage lâche et des autres avantages en aval de l’approvisionnement en événements et de CQRS, tout en minimisant la charge de support liée au dépannage des flux de données hérités. Cela permet à nos développeurs de passer plus de temps à écrire de nouvelles applications et augmente notre valeur pour nos consommateurs.

Si vous avez aimé cet article, cliquez sur le bouton ci-dessous et appliquez-moi des applaudissements pour que plus de gens le voient. Merci!

Jonathan est directeur adjoint de l’architecture et des opérations au département des systèmes d’information sur la recherche de l’UCLA. Après avoir obtenu un diplôme en physique de l'Université de Stanford, il a ensuite travaillé pendant plus de 10 ans dans l'architecture des systèmes d'information, l'amélioration des processus métier pilotée par les données et la gestion organisationnelle. Il est également le fondateur de Peach Pie Apps Workshop, une entreprise spécialisée dans la création de solutions de données pour les organisations à but non lucratif.