Registry-Interna
Registry-Interna
Abschnitt betitelt „Registry-Interna“Die Registry ist ein versionierter, ereignisgesteuerter Zustandsspeicher. Sie pflegt eine vollständige Versionshistorie, unterstützt Transaktionen und verbreitet Änderungen über den Event-Bus.
Entry-Speicherung
Abschnitt betitelt „Entry-Speicherung“Einträge werden als geordnetes Slice mit einer Hash-Map-Index für O(1)-Lookups gespeichert:
type Entry struct { ID ID // namespace:name Kind Kind // Entry-Typ Meta attrs.Bag // Metadaten Data payload.Payload // Inhalt}Entry-IDs verwenden Gos unique-Paket zum Internieren - identische IDs teilen sich denselben Speicher.
Versionskette
Abschnitt betitelt „Versionskette“Jede Version zeigt auf ihren Parent. Pfadberechnung verwendet einen Graph-Algorithmus um die kürzeste Route zwischen zwei Versionen zu finden:
flowchart LR v0[v0] --> v1[v1] --> v2[v2] --> v3[v3] --> vN[vN]ChangeSets
Abschnitt betitelt „ChangeSets“Ein ChangeSet ist eine geordnete Liste von Operationen, die einen Zustand in einen anderen transformieren:
| Operation | OriginalEntry | Zweck |
|---|---|---|
| Create | nil | Neuen Eintrag hinzufügen |
| Update | alter Wert | Existierenden modifizieren |
| Delete | gelöschter Wert | Eintrag entfernen |
OriginalEntry ermöglicht Umkehrung - Updates speichern den vorherigen Wert, Deletes speichern was entfernt wurde.
Deltas erstellen
Abschnitt betitelt „Deltas erstellen“BuildDelta(oldState, newState) generiert minimale Operationen:
- Zustände vergleichen, Änderungen identifizieren
- Deletes in umgekehrter Abhängigkeitsreihenfolge sortieren (Abhängige zuerst)
- Creates/Updates in Vorwärts-Abhängigkeitsreihenfolge sortieren (Abhängigkeiten zuerst)
Squashing
Abschnitt betitelt „Squashing“Mehrere ChangeSets verschmelzen durch Verfolgung des Endzustands pro Eintrag:
Create + Update = Create (mit aktualisiertem Wert)Create + Delete = ∅ (heben sich auf)Update + Delete = DeleteDelete + Create = UpdateTransaktionen
Abschnitt betitelt „Transaktionen“sequenceDiagram participant R as Registry participant B as EventBus participant H as Handlers
R->>B: registry.begin loop Jede Operation R->>B: entry.create/update/delete B->>H: an Listener dispatchen H-->>B: akzeptieren oder ablehnen B-->>R: Bestätigung end alt Alle akzeptiert R->>B: registry.commit else Einer abgelehnt R->>B: registry.discard R->>R: Rollback endHandler haben 30 Sekunden um jede Operation zu akzeptieren oder abzulehnen. Bei Ablehnung führt die Registry ein Rollback durch, indem sie das inverse Delta berechnet und anwendet.
Nicht-propagierende Einträge
Abschnitt betitelt „Nicht-propagierende Einträge“Einige Arten überspringen den Event-Bus komplett:
registry.entry- Anwendungskonfigurationenns.requirement- Namespace-Requirementsns.dependency- Modul-Abhängigkeitenns.definition- Modul-Metadaten (Readme, Lizenz, Autoren)
Abhängigkeitsauflösung
Abschnitt betitelt „Abhängigkeitsauflösung“Einträge können Abhängigkeiten von anderen Einträgen deklarieren. Der Resolver extrahiert Abhängigkeiten über registrierte Muster:
resolver.RegisterPattern(registry.DependencyPattern{ Path: "meta.server", AllowWildcard: true,})Abhängigkeiten werden aus Entry-Meta- und -Data-Feldern extrahiert und dann für topologische Sortierung während Zustandsübergängen verwendet.
Versionshistorie
Abschnitt betitelt „Versionshistorie“History-Backends:
| Implementierung | Anwendungsfall |
|---|---|
| SQLite | Produktions-Persistenz |
| Memory | Testen |
| Nil | Keine Historie |
SQLite verwendet WAL-Modus mit Tabellen für Versionen, ChangeSets (MessagePack-kodiert) und Metadaten.
Navigation
Abschnitt betitelt „Navigation“Pfadberechnung findet die kürzeste Route zwischen Versionen:
Path(v0, v3) = [v1, v2, v3] // ChangeSets vorwärts anwendenPath(v3, v1) = [v2, v1] // Umgekehrte ChangeSets anwendenLoadState() spielt Historie von einer Baseline ab ohne neue Versionen zu erstellen - wird beim Boot verwendet.
Query-Engine mit LRU-Caching für Entry-Suche:
| Operator | Präfix | Beispiel |
|---|---|---|
| Glob | (keiner) | .kind=function.* |
| Regex | ~ | ~meta.path=/api/.* |
| Contains | * | *meta.tags=backend |
| Prefix | ^ | ^meta.name=user |
| Suffix | $ | $meta.path=Handler |
Cache invalidiert bei Versionsänderung.