Skip to content

Drift-Management — Wie Prilog DB und Matrix synchron haelt

Was ist Drift?

Prilog speichert den Soll-Zustand in einer PostgreSQL-Datenbank (Spaces, Mitgliedschaften, Rollen). Matrix/Synapse speichert den Ist-Zustand (Raeume, Mitglieder, Power-Levels). Drift entsteht, wenn beide nicht mehr uebereinstimmen.

Beispiel: Die Prilog-DB sagt "User X ist Mitglied von Space Y", aber in Synapse ist der User nicht im entsprechenden Matrix-Raum.


Wie Drift entsteht

1. Synapse war kurzzeitig nicht erreichbar

Die haeufigste Ursache. Wenn ein User einem Space hinzugefuegt wird, schreibt Prilog in die DB und schickt einen API-Call an Synapse. Wenn Synapse gerade restartet, ueberlastet oder nicht erreichbar ist, schlaegt der Matrix-Call fehl — die DB ist aktualisiert, Matrix nicht.

Typische Ausloeser:

  • Synapse-Container-Restart (Docker-Update, OOM)
  • Netzwerk-Unterbrechung zwischen Backend und Synapse
  • Synapse Rate-Limit bei Massen-Operationen (Bulk-Import von 25 Schuelern)

2. Backend-API wurde restartet waehrend einer Operation

Wenn das Backend mitten in einem Space-Sync restartet wird (z.B. wegen Deployment), kann der DB-Write durchgehen aber der Synapse-Call nicht mehr.

3. Timeout bei grossen Operationen

Bulk-Operationen (viele User auf einmal einem Space zuweisen) koennen laenger dauern als der HTTP-Timeout. Die ersten 15 Memberships werden synchronisiert, dann bricht der Request ab — die restlichen bleiben unsynchronisiert.

4. Matrix-Raum existiert nicht (mehr)

Selten, aber moeglich: Ein Synapse-Admin hat einen Raum manuell geloescht, oder die Raum-Erstellung beim Space-Anlegen ist fehlgeschlagen (z.B. weil das Synapse-Volumen voll war).

5. Power-Level-Konflikt

Wenn ein Space zwischen CHAT und INFOTAFEL umgeschaltet wird, muessen die Matrix Power-Levels angepasst werden. Wenn dabei ein Fehler passiert, stimmen die Berechtigungen nicht mehr.


3-Stufen-Abwehr

Prilog setzt auf drei aufeinander aufbauende Schutzstufen:

Aenderung in Prilog-DB


┌─────────────────────────────────────────┐
│ Stufe 1: Auto-Sync (sofort)            │
│ Bei jeder Mitgliedschafts-Aenderung    │
│ wird synchron ein Synapse-Call gemacht. │
│ Funktioniert in 99% der Faelle.        │
│                                         │
│ Bei Fehler: Space wird als 'pending'    │
│ markiert → Stufe 2 greift.             │
└────────────────┬────────────────────────┘
                 │ Wenn Auto-Sync fehlschlaegt

┌─────────────────────────────────────────┐
│ Stufe 2: Naechtlicher Drift-Scan       │
│ Cron-Job um 02:00 — prueft ALLE Spaces │
│ und Memberships gegen Synapse.         │
│                                         │
│ Bei Drift: automatische Reparatur.     │
│ Ergebnis im Cron-Log + Portal.         │
│                                         │
│ Wenn Repair fehlschlaegt: bleibt       │
│ 'drifted' → Stufe 3 greift.           │
└────────────────┬────────────────────────┘
                 │ Wenn Auto-Repair fehlschlaegt

┌─────────────────────────────────────────┐
│ Stufe 3: Health-Monitor + Alert        │
│ Alle 15 Minuten: prueft ob Drift       │
│ nach Repair noch besteht.              │
│                                         │
│ Bei verbleibendem Drift:               │
│ → Alert-Mail an Admin                  │
│ → Sichtbar im Portal unter "Wartung"   │
│ → Manueller "Reparieren"-Button        │
└─────────────────────────────────────────┘

Stufe 1: Auto-Sync (sofort, bei jeder Aenderung)

Jede Mitgliedschafts-Aenderung (Hinzufuegen, Entfernen, Rolle aendern) loest einen synchronen Synapse-Call aus. Das Backend wartet auf die Antwort und markiert den Sync-Status:

  • synced — Matrix-State stimmt mit DB ueberein
  • pending — Matrix-Call fehlgeschlagen, wird beim naechsten Scan repariert
  • failed — Wiederholter Fehler

Code: customer-sync.service.tsrunSpaceSync(), runMembershipSync()

Stufe 2: Naechtlicher Drift-Scan mit Auto-Repair

Cron-Job space-drift-scan (taeglich 02:00). Geht ueber alle aktiven Spaces aller Tenants und vergleicht den DB-Zustand mit dem Matrix-Zustand.

Drei Repair-Szenarien:

Drift-TypErkennungAuto-Repair
Space ohne Matrix-RaummatrixRoomId = nullinitializeSpaceInMatrix() erstellt den Raum
Space-Zustand weicht abrunSpaceSync() meldet driftedErneuter runSpaceSync()
Membership fehlt in MatrixrunMembershipSync() meldet driftedErneuter runMembershipSync()

Code: space-drift-scan.tsrunDriftScan()

Cron-Log Beispiel:

Drift-Scan: 24 Spaces (22 ok, 1 drifted, 0 failed, 1 auto-repariert),
            156 Memberships (2 drifted, 2 auto-repariert)

Stufe 3: Health-Monitor (alle 15 Minuten)

Der Health-Monitor-Cron prueft:

  1. Agent-Verbindung — ist der Server-Agent online?
  2. Synapse-Erreichbarkeit — antwortet /_matrix/client/v3/login?
  3. Verbleibender Drift — gibt es Spaces mit syncStatus = drifted/failed?

Bei Problemen: Alert-Mail an den Admin mit Problemliste.

Code: core/cron/jobs.tssystem-health-monitor


Was der Admin sieht

Portal: Wartungs-Seite

Unter Benutzerkonten → Wartung sieht der Tenant-Admin alle Spaces mit Drift. Pro Space gibt es einen "Reparieren"-Button der die Synchronisation manuell anstosst.

Im Normalfall ist diese Liste leer — Stufe 1 und 2 raeumen den Drift automatisch weg.

Portal: Systemstatus

Unter Benutzerkonten → Systemstatus zeigt der Health-Check den Gesamtzustand inkl. Sync-Status aller Spaces.

Admin-Panel: admin.prilog.chat

GET /admin/health zeigt pro Server:

  • Agent-Status (verbunden/getrennt)
  • Synapse-Status (erreichbar/nicht erreichbar)
  • Drift-Count (Anzahl Spaces mit Problemen)

Warum nicht einfach eine Queue?

Man koennte argumentieren: "Statt Drift zu reparieren, benutze eine Message-Queue (Redis/Bull) die fehlgeschlagene Syncs automatisch wiederholt."

Gruende dagegen (fuer jetzt):

  1. Komplexitaet: Eine Queue braucht Worker-Prozesse, Dead-Letter-Handling, Retry-Logik, Monitoring. Der Drift-Scan ist ~130 Zeilen und lauft als einfacher Cron.
  2. Seltenheit: Drift passiert vielleicht 1-2x pro Woche. Eine Queue die 99.9% der Zeit leer ist, ist Overhead.
  3. Idempotenz: runSpaceSync und runMembershipSync sind idempotent — man kann sie beliebig oft aufrufen. Das macht den Scan-und-Repair-Ansatz robust.

Wenn Drift haeufiger wird (>10 Faelle pro Tag), lohnt sich eine Queue. Bis dahin reicht der 3-Stufen-Ansatz.


Drift in Zahlen (Testinstanz weser, April 2026)

MetrikWert
Spaces gesamt24
Drift-Faelle pro Woche~2
Davon auto-repariert~2
Manuell repariert (Stufe 3)0
Durchschnittliche Scan-Dauer~5s