Événements de domaine
Qu’est-ce qu’un événement de domaine
Section intitulée “Qu’est-ce qu’un événement de domaine”Les événements de domaine sont le mécanisme de découplage qui permet aux fonctionnalités de communiquer sans dépendances directes. Plutôt que la fonctionnalité A n’appelle la fonctionnalité B, la fonctionnalité A publie un événement et la fonctionnalité B s’y abonne.
Le DomainEventBus est un bus de publication/abonnement par diffusion, à
l’intérieur du processus. Les éditeurs appellent publish(event); les abonnés
consomment un flux typé on<T>(). Chaque événement implémente DomainEvent et
porte occurredAt.
Le bus s’exécute à l’intérieur de cc_server. Chaque éditeur et chaque
abonné actif y réside. Aucun client ne voit ce bus. Ce qu’un client voit, c’est
un sous-ensemble choisi que le serveur réémet sous forme de trames JSON-RPC
notifications/*.
Pourquoi un bus, au fond
Section intitulée “Pourquoi un bus, au fond”Sans événements, chaque réaction transversale est un import. Le chemin des notifications devrait importer la fonctionnalité des agents, celle des demandes de tirage, la billetterie et les réunions juste pour savoir quand afficher un toast — et chacune de ces fonctionnalités devrait ensuite savoir que les notifications existent. La billetterie importerait les pipelines pour qu’un ticket terminé puisse faire avancer une exécution. Le graphe de dépendances se referme en nœud, et le noyau partagé cesse d’être partagé.
Publier un événement brise cette spirale. Le chemin des notifications s’abonne à vingt et une classes d’événements et n’importe aucune des fonctionnalités qui les lèvent. Le répartiteur de déclencheurs de pipeline s’abonne à tout le bus et ne connaît rien des demandes de tirage, des tickets ni des réunions. L’observabilité agrège les issues d’exécution sans s’immiscer dans le lancement.
Le coût est celui auquel on s’attend : un éditeur ne peut pas savoir si
quelqu’un écoute, et un écouteur jamais construit reste silencieusement inerte.
TicketRemoteSyncHandler en est l’exemple permanent : il est déclaré, couvert
par des tests et jamais câblé en production.
Ce que le bus n’est pas
Section intitulée “Ce que le bus n’est pas”Il vaut la peine d’être précis sur une chose que le bus ne possède pas.
La piste d’audit n’est pas une projection du flux d’événements. Chaque
opération RPC qui modifie l’état est auditée par défaut — RepoOp.audited vaut
true par défaut et une opération ne s’y soustrait qu’en déclarant
audited: false, un acte délibéré visible sur l’opération elle-même. Le
répartiteur ajoute la ligne « qui a fait quoi, d’où » directement après un appel
réussi. Il n’existe pas de DomainEventAuditBridge. ActivityLogPersister écrit
les lignes activity_log à partir des événements ActivityLogged; c’est un flux
distinct de l’audit RPC.
Le bus d’événements est le transport des notifications et de l’automatisation. Il n’est pas le registre de référence.
Ce que le bus pilote
Section intitulée “Ce que le bus pilote”- Notifications. Vingt et une classes d’événements sont transformées en
trames
notifications/*par le serveur, consignées dans un fil durable par espace de travail et diffusées aux sessions connectées. Une trame dont leworkspace_iddésigne un espace de travail dont l’utilisateur de la session n’est pas membre est écartée sur le serveur; le client filtre ensuite le reste selon l’espace de travail qu’il consulte. - Automatisation pilotée par les événements. Les déclencheurs de pipeline s’abonnent au bus et démarrent automatiquement les pipelines correspondants (voir ci-dessous).
- Réactions de cycle de vie. La création d’un espace de travail initialise son agent CEO et ses agents spécialisés, les modèles de pipeline intégrés et les suites d’évaluation de départ. Une exécution d’agent terminée reprend une étape de pipeline suspendue, ferme une tâche, alimente le superviseur des objectifs, peut réveiller un vérificateur nommé et peut relancer un chef d’équipe. Une PR fusionnée ou un espace supprimé déclenche le nettoyage des arbres de travail.
- Synchronisation entre fournisseurs. Les changements locaux apportés aux tickets sont poussés vers les fournisseurs configurés par un coordinateur à l’écoute de cinq événements de ticket.
Catégories d’événements
Section intitulée “Catégories d’événements”Les événements couvrent toute la surface du produit. En gros :
- Espaces de travail, agents et dépôts — création d’espace de travail, fin d’exécution, enregistrement de dépôt, mises à jour de skills
- Demandes de tirage — publication, changements de statut, fusions, demandes de révision, mentions, surveillance des PR dont vous êtes l’auteur, PR détectées de l’extérieur
- Messagerie — messages, espaces et progression du provisionnement des espaces
- Tickets — création, assignation, réassignation, détails, statut et les trois issues terminales
- Tâches — trames de cycle de vie séquencées pour une exécution lancée, afin que les clients puissent les ordonner et les dédoublonner
- Pipelines — événements d’exécution terminaux seulement (terminée, annulée, échouée)
- Observabilité — entrées du journal d’activité et seuils budgétaires
- Identité et appartenance — membre ajouté, retiré, rôle modifié
- Calendrier et réunions — expiration de l’authentification, début des réunions et fin des enregistrements
- Rigs — prise de contrôle, récupération et fermeture inattendue
La mémoire, l’orchestration, les documents de plan, les artéfacts, les approbations, la réception de synchronisation des tickets, l’actualisation du calendrier, les fusions d’arbres de travail, la création d’utilisateur, les invitations et la révocation d’appareil ne sont pas des événements de domaine; consultez la référence.
Pour le catalogue complet — les 53 classes d’événements concrètes, leurs charges utiles et les 24 abonnés qui les consomment — consultez la référence des événements de domaine. Cette page est l’inventaire; celle-ci est le modèle.
Le contrôle d’accès en direct repose sur deux mécanismes distincts
Section intitulée “Le contrôle d’accès en direct repose sur deux mécanismes distincts”Les événements d’appartenance et d’appareil semblent symétriques et ne le sont pas, ce qui compte si vous réfléchissez à la vitesse à laquelle une révocation prend effet.
Révoquer un appareil met bel et bien fin à ses sessions. Le serveur surveille la table des appareils associés et abandonne toute session active dont l’appareil a quitté l’ensemble actif, en quelques secondes.
Retirer un membre ne ferme pas la connexion. WorkspaceMemberRemoved est
consommé : LocalRpcServer et RemoteRelayHost abandonnent les abonnements
d’espace de travail rattachés à cet utilisateur, et RemoteEventForwarder
invalide son cache d’appartenance afin que d’autres trames visant cet espace de
travail ne soient plus poussées. Ce qui refuse le prochain appel RPC, c’est
toujours le contrôle de rôle, qui résout à nouveau l’appartenance à chaque
appel — sa requête suivante est donc refusée avec
« Not a member of this workspace ». L’effet est immédiat pour tout ce qu’il tente
de faire; il n’est simplement pas obtenu en mettant fin à sa connexion.
Déclencheurs de pipeline
Section intitulée “Déclencheurs de pipeline”Les déclencheurs de pipeline s’abonnent aux événements de domaine et démarrent
automatiquement les pipelines correspondants. PipelineTriggerDispatcher écoute
tout le bus, puis :
- Court-circuite à moins que le type d’événement fasse partie de ceux qu’il sait convertir en charge utile
- Recherche les déclencheurs activés correspondant à ce type d’événement, dans tous les espaces de travail
- Filtre chacun selon son propre espace de travail et applique son filtre de correspondance de charge utile
- Démarre une exécution pour chaque déclencheur qui survit
La contrainte importante est l’étape 1. Le bus transporte 53 types d’événements;
le sélecteur d’ajout de déclencheur démarre une exécution pour ces quatorze
(branches de charge utile de EventPayloadMapper) :
ExternalPrDetected, PullRequestPublished, PullRequestStatusChanged,
PrMerged, MessageReceived, TicketAssigned,
TicketCompleted, TicketFailed, TicketCancelled,
BudgetThresholdCrossed, RepoAdded, MeetingRecordingStopped, SkillUpdated
et SpaceDeleted. Rien d’autre ne peut démarrer un pipeline.
Comment un client voit tout cela
Section intitulée “Comment un client voit tout cela”RemoteEventForwarder traduit les événements de classe notification en trames
et les pousse par RPC vers les sessions connectées, où un mappeur de trames les
transforme en notifications dans l’application. Un client léger voit donc une
projection du flux d’événements du serveur sans posséder d’exécution — ce qui est
tout l’intérêt de la séparation client léger.
Toutes les trames poussées ne sont pas des notifications, par contre. Le flux de cycle de vie des tâches et la réassignation des tickets sont transmis en direct pour piloter l’interface, mais ils ne sont pas consignés dans le fil de notifications et n’affichent aucun toast.
Voir aussi
Section intitulée “Voir aussi”- Pipelines et automatisation : ce qu’un déclencheur démarre
- Tickets et délégation : assignation à un agent ou à une équipe
- Architecture : comment les événements respectent la règle de dépendance
- Référence des événements de domaine : le catalogue complet et ses abonnés
- Configurer des déclencheurs de pipeline
- Configurer les notifications