Synchronisierungs-Mechanismus

Synchronisierungs-Mechanismus

Detaillierte Beschreibung, wie die Dateisynchronisierung intern funktioniert.


Ablauf einer Synchronisierung

1. SyncValidator::canSync() — Vorprüfung
2. Status → 'running'
3. Für jeden Execution Step (1 oder 2 bei bidirektional):
   a. resolveFilesToSync() — Dateien bestimmen
   b. getFileSizeEstimates() — Größen schätzen
   c. splitIntoBatches() — in Batches aufteilen
   d. Für jeden Batch:
      i.   compressFiles() auf Quell-Server → .tar.gz
      ii.  JWT-Token erstellen (15 Min. gültig)
      iii. Download-URL: {node}/download/file?token={jwt}
      iv.  HTTP POST /api/servers/{uuid}/files/pull
      v.   decompressFile() auf Ziel-Server
      vi.  Archive auf beiden Servern löschen
4. Status → success | partial | failed
5. SyncLog erstellen

Inkrementeller Sync

  • Erster Sync (last_sync_at = null): Alle Dateien werden synchronisiert
  • Folgende Syncs: Nur Dateien mit modified > last_sync_at
  • Verzeichnisse: Rekursive Suche nach geänderten Dateien (max. 10 Ebenen)
  • Bei Fehlern: Datei wird sicherheitshalber einbezogen

Batch-Splitting

Wenn die geschätzten Dateigrößen max_file_size_mb überschreiten:

  1. Dateien nach Größe sortieren (absteigend)
  2. First-Fit-Decreasing Algorithmus: Neuer Batch wenn aktuellerBatch + nächsteDatei > Limit
  3. Einzelne Dateien größer als das Limit bekommen einen eigenen Batch
  4. Archivname: .server_sync_{pairId}_{timestamp}_b{batchNum}.tar.gz

Exclude Paths Matching

Ein Pfad gilt als ausgeschlossen wenn:

  • Exakter Match: trim(pfad) === trim(exclude)
  • Prefix-Match: str_starts_with(pfad, exclude + '/')

Beispiel: Exclude logs → schließt logs, logs/server.log, logs/2026/error.log aus.


Archiv-Cleanup

  • Temporäre Archive werden auf beiden Servern gelöscht
  • Bei Fehlern: Best-Effort-Cleanup (Fehler werden nur geloggt)
  • Archivnamen beginnen mit .server_sync_ (versteckt)
  • Im Full-Scope-Sync werden eigene Archive automatisch übersprungen

Datei-Detail-Expansion

Top-Level-Verzeichnisse werden in individuelle Dateipfade aufgelöst:

  • Maximal 500 Einträge
  • Rekursive Auflistung bis Tiefe 5
  • Leere Verzeichnisse: "dirname/" als Eintrag