Μετάβαση στο περιεχόμενο

Γεγονότα τομέα

Τα γεγονότα τομέα είναι ο μηχανισμός αποσύνδεσης που επιτρέπει στις λειτουργικές ενότητες να επικοινωνούν χωρίς άμεσες εξαρτήσεις. Αντί η ενότητα A να καλεί την ενότητα B, η ενότητα A δημοσιεύει ένα γεγονός και η ενότητα B εγγράφεται σε αυτό.

Ο DomainEventBus είναι ένας ενδοδιεργασιακός δίαυλος δημοσίευσης/συνδρομής με εκπομπή. Οι εκδότες καλούν publish(event)· οι συνδρομητές καταναλώνουν μια ροή on<T>() με τύπο. Κάθε γεγονός υλοποιεί το DomainEvent και φέρει occurredAt.

Ο δίαυλος εκτελείται μέσα στο cc_server. Κάθε εκδότης και κάθε ενεργός συνδρομητής βρίσκεται εκεί. Κανένας πελάτης δεν βλέπει αυτόν τον δίαυλο. Αυτό που βλέπει ένας πελάτης είναι ένα επιμελημένο υποσύνολο που ο διακομιστής επανεκπέμπει ως πλαίσια JSON-RPC notifications/*.

Χωρίς γεγονότα, κάθε αντίδραση ανάμεσα σε λειτουργικές ενότητες είναι μια εισαγωγή. Η διαδρομή των ειδοποιήσεων θα έπρεπε να εισάγει την ενότητα των πρακτόρων, την ενότητα των pull request, τα εισιτήρια και τις συσκέψεις μόνο και μόνο για να ξέρει πότε να εμφανίσει ένα αναδυόμενο μήνυμα — και καθεμία από αυτές θα έπρεπε τότε να γνωρίζει ότι υπάρχουν οι ειδοποιήσεις. Τα εισιτήρια θα εισήγαγαν τα pipeline, ώστε ένα ολοκληρωμένο εισιτήριο να μπορεί να προωθήσει μια εκτέλεση. Το γράφημα εξαρτήσεων κλείνει σε κόμπο και ο κοινόχρηστος πυρήνας παύει να είναι κοινόχρηστος.

Η δημοσίευση ενός γεγονότος το σπάει αυτό. Η διαδρομή των ειδοποιήσεων εγγράφεται σε είκοσι μία κλάσεις γεγονότων και δεν εισάγει καμία από τις ενότητες που τις προκαλούν. Ο αποστολέας ενεργοποιητών pipeline εγγράφεται σε ολόκληρο τον δίαυλο και δεν γνωρίζει τίποτα για pull requests, εισιτήρια ή συσκέψεις. Οι συγκεντρώσεις παρατηρησιμότητας συνοψίζουν τα αποτελέσματα εκτελέσεων χωρίς να επεμβαίνουν στην αποστολή.

Το κόστος είναι το συνηθισμένο: ένας εκδότης δεν μπορεί να ξέρει αν κάποιος ακούει, και ένας ακροατής που δεν κατασκευάζεται ποτέ μένει σιωπηλά αδρανής. Ο TicketRemoteSyncHandler είναι το πάγιο παράδειγμα: έχει δηλωθεί, καλύπτεται από τεστ και δεν συνδέεται ποτέ στην παραγωγή.

Αξίζει να είμαστε ακριβείς σε ένα πράγμα που ο δίαυλος δεν κατέχει.

Το ίχνος ελέγχου δεν είναι προβολή της ροής γεγονότων. Κάθε λειτουργία RPC που μεταβάλλει δεδομένα καταγράφεται στο ίχνος ελέγχου εξ ορισμού — το RepoOp.audited έχει προεπιλογή true και μια λειτουργία εξαιρείται μόνο δηλώνοντας audited: false, μια σκόπιμη πράξη ορατή στην ίδια τη λειτουργία. Ο αποστολέας προσθέτει τη γραμμή «ποιος έκανε τι, από πού» αμέσως μετά από μια επιτυχημένη κλήση. Δεν υπάρχει DomainEventAuditBridge. Το ActivityLogPersister γράφει γραμμές activity_log από γεγονότα ActivityLogged· αυτή είναι ξεχωριστή ροή από το ίχνος ελέγχου του RPC.

Ο δίαυλος γεγονότων είναι το μέσο μεταφοράς για τις ειδοποιήσεις και για τον αυτοματισμό. Δεν είναι το λογιστικό σύστημα αναφοράς.

  • Ειδοποιήσεις. Είκοσι μία κλάσεις γεγονότων μετατρέπονται από τον διακομιστή σε πλαίσια δικτύου notifications/*, καταγράφονται σε μια μόνιμη ροή ανά χώρο εργασίας και εκπέμπονται σε όλες τις συνδεδεμένες συνεδρίες. Ένα πλαίσιο του οποίου το workspace_id ονομάζει χώρο εργασίας στον οποίο ο χρήστης της συνεδρίας δεν είναι μέλος απορρίπτεται στον διακομιστή· στη συνέχεια ο πελάτης φιλτράρει τα υπόλοιπα στον χώρο εργασίας που κοιτάζει.
  • Αυτοματισμός που καθοδηγείται από γεγονότα. Οι ενεργοποιητές pipeline εγγράφονται στον δίαυλο και ξεκινούν αυτόματα τα pipeline που ταιριάζουν (δείτε παρακάτω).
  • Αντιδράσεις κύκλου ζωής. Η δημιουργία ενός χώρου εργασίας εφοδιάζει τον CEO και τους εξειδικευμένους πράκτορές του, τα ενσωματωμένα πρότυπα pipeline και τις αρχικές σουίτες αξιολόγησης. Μια ολοκληρωμένη εκτέλεση πράκτορα συνεχίζει ένα βήμα pipeline που βρίσκεται σε αναστολή, κλείνει μια εργασία, τροφοδοτεί τον επόπτη στόχων, μπορεί να αφυπνίσει έναν επώνυμο ελεγκτή και μπορεί να ενεργοποιήσει ξανά έναν ηγέτη ομάδας. Ένα συγχωνευμένο PR ή ένας διαγραμμένος χώρος προκαλεί τη συλλογή απορριμμάτων των worktree.
  • Συγχρονισμός μεταξύ προμηθευτών. Οι τοπικές αλλαγές εισιτηρίων αποστέλλονται στους διαμορφωμένους προμηθευτές από έναν συντονιστή που ακούει πέντε γεγονότα εισιτηρίων.

Τα γεγονότα καλύπτουν ολόκληρη την επιφάνεια του προϊόντος. Σε γενικές γραμμές:

  • Χώροι εργασίας, πράκτορες και αποθετήρια — δημιουργία χώρου εργασίας, ολοκλήρωση εκτέλεσης, καταχώριση αποθετηρίου, ενημερώσεις δεξιοτήτων
  • Pull requests — δημοσίευση, αλλαγές κατάστασης, συγχωνεύσεις, αιτήματα ανασκόπησης, αναφορές, παρακολούθηση PR που συντάξατε, PR που εντοπίστηκαν εξωτερικά
  • Μηνύματα — μηνύματα, χώροι και πρόοδος παροχής χώρων
  • Εισιτήρια — δημιουργία, ανάθεση, εκ νέου ανάθεση, λεπτομέρειες, κατάσταση και τα τρία τελικά αποτελέσματα
  • Εργασίες — αλληλουχημένα πλαίσια κύκλου ζωής για μία αποστολή, ώστε οι πελάτες να μπορούν να τα ταξινομούν και να αφαιρούν διπλότυπα
  • Pipeline — μόνο τελικά γεγονότα εκτέλεσης (ολοκληρώθηκε, ακυρώθηκε, απέτυχε)
  • Παρατηρησιμότητα — καταχωρίσεις αρχείου καταγραφής δραστηριότητας και όρια προϋπολογισμού
  • Ταυτότητα και ιδιότητα μέλους — προσθήκη μέλους, αφαίρεση, αλλαγή ρόλου
  • Ημερολόγιο και συσκέψεις — λήξη ταυτοποίησης, έναρξη συσκέψεων και ολοκλήρωση καταγραφών
  • Σταθμοί — ανάληψη, περισυλλογή και απροσδόκητο κλείσιμο

Η μνήμη, η ενορχήστρωση, τα έγγραφα σχεδίων, τα τεχνουργήματα, οι εγκρίσεις, η είσοδος συγχρονισμού εισιτηρίων, η ανανέωση ημερολογίου, οι συγχωνεύσεις worktree, η δημιουργία χρηστών, οι προσκλήσεις και η ανάκληση συσκευών δεν είναι γεγονότα τομέα· δείτε την αναφορά.

Για τον πλήρη κατάλογο — και τις 53 συγκεκριμένες κλάσεις γεγονότων, τα φορτία τους και τους 24 συνδρομητές που τις καταναλώνουν — δείτε την Αναφορά γεγονότων τομέα. Εκείνη η σελίδα είναι το ευρετήριο· αυτή εδώ είναι το μοντέλο.

Ο ζωντανός έλεγχος πρόσβασης βασίζεται σε δύο διαφορετικούς μηχανισμούς

Ενότητα με τίτλο «Ο ζωντανός έλεγχος πρόσβασης βασίζεται σε δύο διαφορετικούς μηχανισμούς»

Τα γεγονότα ιδιότητας μέλους και τα γεγονότα συσκευών φαίνονται συμμετρικά αλλά δεν είναι, κάτι που έχει σημασία αν συλλογίζεστε πόσο γρήγορα τίθεται σε ισχύ μια ανάκληση.

Η ανάκληση μιας συσκευής τερματίζει όντως τις συνεδρίες της. Ο διακομιστής παρακολουθεί τον πίνακα συζευγμένων συσκευών και απορρίπτει κάθε ζωντανή συνεδρία της οποίας η συσκευή έφυγε από το ενεργό σύνολο, μέσα σε δευτερόλεπτα.

Η αφαίρεση ενός μέλους δεν κλείνει την υποδοχή. Το WorkspaceMemberRemoved καταναλώνεται: τα LocalRpcServer και RemoteRelayHost απορρίπτουν τις συνδεδεμένες συνδρομές χώρου εργασίας αυτού του χρήστη και το RemoteEventForwarder ακυρώνει την προσωρινή μνήμη ιδιότητας μέλους, ώστε να μην αποστέλλονται άλλα πλαίσια για αυτόν τον χώρο εργασίας. Αυτό που αρνείται το επόμενο RPC είναι ακόμη ο έλεγχος ρόλου, ο οποίος επιλύει ξανά την ιδιότητα μέλους σε κάθε κλήση — οπότε το επόμενο αίτημά τους απορρίπτεται με «Not a member of this workspace». Το αποτέλεσμα είναι άμεσο για οτιδήποτε προσπαθήσουν να κάνουν· απλώς δεν επιτυγχάνεται κλείνοντάς τους τη σύνδεση.

Οι ενεργοποιητές pipeline εγγράφονται σε γεγονότα τομέα και ξεκινούν αυτόματα τα pipeline που ταιριάζουν. Ο PipelineTriggerDispatcher ακούει ολόκληρο τον δίαυλο και στη συνέχεια:

  1. Συντομεύει τη διαδικασία, εκτός αν ο τύπος γεγονότος είναι ένας από αυτούς που ξέρει να αντιστοιχίζει σε φορτίο
  2. Αναζητά ενεργοποιημένους ενεργοποιητές που ταιριάζουν με αυτόν τον τύπο γεγονότος, σε κάθε χώρο εργασίας
  3. Φιλτράρει τον καθένα στον δικό του χώρο εργασίας και εφαρμόζει το φίλτρο αντιστοίχισης φορτίου του
  4. Ξεκινά μια εκτέλεση για κάθε ενεργοποιητή που επιβιώνει

Ο σημαντικός περιορισμός είναι το βήμα 1. Ο δίαυλος μεταφέρει 53 τύπους γεγονότων· ο επιλογέας προσθήκης ενεργοποιητή ξεκινά εκτέλεση για τους εξής δεκατέσσερις (διακλαδώσεις φορτίου του EventPayloadMapper): ExternalPrDetected, PullRequestPublished, PullRequestStatusChanged, PrMerged, MessageReceived, TicketAssigned, TicketCompleted, TicketFailed, TicketCancelled, BudgetThresholdCrossed, RepoAdded, MeetingRecordingStopped, SkillUpdated και SpaceDeleted. Τίποτα άλλο δεν μπορεί να ξεκινήσει ένα pipeline.

Ο RemoteEventForwarder μεταφράζει τα γεγονότα κλάσης ειδοποιήσεων σε πλαίσια δικτύου και τα αποστέλλει μέσω RPC στις συνδεδεμένες συνεδρίες, όπου ένας αντιστοιχιστής πλαισίων τα μετατρέπει σε ειδοποιήσεις εντός εφαρμογής. Ένας λεπτός πελάτης βλέπει επομένως μια προβολή της ροής γεγονότων του διακομιστή χωρίς να κατέχει καμία εκτέλεση — που είναι όλο το νόημα του διαχωρισμού λεπτού πελάτη.

Δεν είναι όμως κάθε πλαίσιο που αποστέλλεται και μια ειδοποίηση. Η ροή κύκλου ζωής εργασιών και η εκ νέου ανάθεση εισιτηρίων προωθούνται ζωντανά για να τροφοδοτήσουν τη διεπαφή χρήστη, αλλά δεν καταγράφονται στη ροή ειδοποιήσεων και δεν εμφανίζουν αναδυόμενο μήνυμα.