# Standard-Pipeline für die Synchronisierung

Dieses Dokument beschreibt die Standard-Pipeline, die ELO Sync für die Datensynchronisation verwendet.

Je nach Art und Richtung des Synchronisierungsauftrags werden Elemente zur Pipeline hinzugefügt oder aus ihr entfernt.

# Übersicht

Eine Synchronisationspipeline kann aus einer unbegrenzten Anzahl von Stufen bestehen, die aktuelle Standardpipeline verwendet zwei Stufen.

Jede Stufe enthält eine Reihe von Middlewares, die jeweils einen einzelnen Schritt für einen synchronisierten Eintrag ausführen.

Die nächste Stufe beginnt erst, wenn alle Einträge in den vorangegangenen Stufen bearbeitet wurden. Dadurch wird sichergestellt, dass einige Vorgänge immer nach anderen ausgeführt werden.

flowchart LR
start(Quelle) --> def-pipeline-stage
subgraph def-pipeline [Standardpipeline]
    direction TB
    subgraph def-pipeline-stage [Standardphase]
        direction TB
        automapping(Automatische Zuordnung)
        --> itemresolution(Verknüpfte Elemente behandeln)
        --> deduplication(Duplizierte Elemente auflösen)
        --> entry-limit(Anzahl-Limit beachten)
        --> size-limit(Größen-Limit beachten)
        --> classification(Elemente klassifizieren)
        --> difference(Unterschiede zwischen Elementen herausfinden)
        --> conflicts(Konflikte lösen)
        --> execution(Nicht-destruktive Änderungen anwenden)
    end
    subgraph deletion-pipeline-stage [Löschphase]
        execution2(Destruktive Änderungen anwenden)
    end
    def-pipeline-stage --> deletion-pipeline-stage
end

Die Standard- und Löschphasen werden seriell und nicht parallel ausgeführt.

Dadurch wird sichergestellt, dass Änderungen immer in der richtigen Reihenfolge ausgeführt werden und dass destruktive Änderungen die erfolgreiche Ausführung anderer Änderungen nicht verhindern.

Darüber hinaus vereinfacht es die Anwendung von nicht-destruktiven Änderungen, da diese keine zusätzlichen Einschränkungen überprüfen müssen.

# Gründe für die zweistufige Pipeline

Derzeit gibt es nur einen Grund für die Verwendung einer zweistufigen Pipeline:

Die Kombination aus dem Verschieben eines Elements und dem Löschen seines (indirekten) übergeordneten Elements zwischen zwei Synchronisationen.

In allen derzeit unterstützten Systemen wird beim Löschen eines Ordners auch sein gesamter Inhalt gelöscht. Dies führt zu einem Problem, wenn ein Element aus einem Ordner verschoben und der Ordner anschließend gelöscht wird.

Aus Performancegründen wird der Synchronisationscode immer parallel für jeden Eintrag ausgeführt, sodass es möglich ist, dass der Ordner im Zielsystem gelöscht wird, bevor das Element verschoben wurde.

Information

Man könnte meinen, dass eine offensichtliche Lösung darin bestünde, die aufgezeichneten Änderungen in der Reihenfolge ihres Auftretens zu ordnen, aber dies kann in Grenzfällen zu kleinen Fehlern führen:

  1. Es ist nicht garantiert, dass die synchronisierten Systeme genaue Uhren verwenden.
  2. Die Synchronisierung kann weit nach den Änderungen erfolgen, und bei einer Zwei-Wege-Synchronisierung wird das Objekt in einem System verschoben und der Ordner im anderen System gelöscht.

Da sich der Synchronisierungscode nicht auf die Genauigkeit der gemeldeten Zeitstempel verlassen kann, muss eine andere Lösung gefunden werden, damit diese Vorgänge erfolgreich durchgeführt werden können.

Die derzeitige Lösung besteht darin, alle destruktiven Änderungen nur in einer Warteschlange zu erfassen, die nach der Verarbeitung aller anderen Änderungen ausgeführt wird.

# Beispiel

Gehen Sie in beiden Systemen von der folgenden Ausgangsstruktur aus:

  • Folder A
    • File F1
    • File F2
  • Folder B

Zwischen zwei Synchronisationsläufen verschiebt ein Benutzer die Datei F1 nach B und löscht anschließend den Ordner A.

Um diesen Vorgang korrekt zu wiederholen, müssen die Änderungen in der gleichen Reihenfolge durchgeführt werden.

Bitte beachten Sie, dass die Verschiebe- und Löschaktion nicht auf demselben System ausgeführt werden muss und daher nicht garantiert werden kann, dass die Zeitstempel (oder ähnliche) vergleichbar sind.

Information

Zeitstempel können zwischen Systemen unterschiedlich sein, z. B. weil ein System einfach die falsche Zeit eingestellt hat oder ein NTP-Zeitserver vorübergehend unerreichbar war.

Es gibt viele Ursachen für unzuverlässige Zeitstempel.

Eine allgemeine Empfehlung für zuverlässige Systeme lautet, bei der Entscheidung über Aktionen keine Zeitstempel zu verwenden.

# Source

Die Quelle für die Synchronisation holt die Positionen aus den einzelnen Systemen zur Verarbeitung und stellt sie anderen Komponenten zur Verfügung.

Alle lesbaren Systeme werden in die Verarbeitungswarteschlange für die Quelle eingefügt, und dann wird ein Generatorblock erstellt, der die Elemente abruft und sie für die weitere Verarbeitung bereitstellt. Der Generatorblock startet eine Anzahl von parallelen Workern zwischen 1 und der Anzahl der zu synchronisierenden Systeme.

Jeder Worker holt Elemente aus der Verarbeitungswarteschlange und führt je nach Art der Elemente unterschiedliche Aktionen durch.

Für ein System holt der Worker seine Root Collection und fügt alle von dieser Collection bereitgestellten Root-Elemente in die Verarbeitungswarteschlange ein. Die Elemente werden in Blöcken von bis zu acht Elementen gruppiert, sodass die spätere Verarbeitung mehrere Abrufe oder Änderungen zusammenfassen kann.

Handelt es sich bei dem verarbeiteten Element um ein Provider-Element einer anderen Sammlung, wird diese Sammlung abgerufen und ihre Root-Elemente werden in die Verarbeitungswarteschlange eingefügt. Andernfalls werden die Kinder des Eintrags abgerufen, in Gruppen von acht Einträgen unterteilt und dann wie Einträge in einem System verarbeitet.

# Executor

Der Executor führt jede konfigurierte Pipelinestufe seriell aus, und innerhalb jeder Stufe alle Einträge parallel.

Für die erste Stufe wird der Quellblock aus der Quelle entnommen und verarbeitet, spätere Stufen verarbeiten jeweils die Warteschlange für ihre Stufe als Quellblock.

Nach Erhalt eines Eingangskontextes zur Bearbeitung prüft der Executor, ob der aktuelle Kontext einen Vorgänger hat und wartet, bis er beendet ist, falls ein solcher gesetzt ist. Danach startet der Executor die eigentliche Ausführung der Middlewares, die für die Stufe konfiguriert wurden.

# Middlewares

# Automatische Zuordnung

Diese ordnet automatisch Objekte zwischen verschiedenen Systemen anhand verschiedener Kriterien zu.

Die Standardkonfiguration für diese Middleware ordnet Elemente auf der Grundlage ihres relativen Pfads innerhalb der synchronisierten Struktur zu.

# Beispiel

Falls eine Dokumentenbibliothek in SharePoint Online eine Datei an dem Pfad Project/Marketing/Presentation.pptx besitzt, dann wird in dem ELO Repository nach einem Ordner Project gesucht, innerhalb des Ordners nach einem Ordner Marketing, und darin nach einem Dokument mit der Kurzbezeichnung Presentation mit einer aktuellen Version, die die Dateiendung .pptx besitzt.

# Verknüpfte Elemente behandeln

Diese wird benötigt, wenn frühere Schritte in der Pipeline nur die Ids der Elemente bestimmen konnten, aber die Elemente selbst nicht abgerufen haben.

Diese Middleware sucht dann in der Datenbank nach den Metadaten dieser Elemente und fragt, wenn möglich, die Systeme, zu denen sie gehören, ab, ob diese Elemente existieren (oder gelöscht wurden).

Damit ist gewährleistet, dass alle späteren Middlewares zumindest Zugriff auf die Metadaten und den Status dieser Elemente haben. Wenn Elemente gelöscht wurden, werden diese Elemente durch entsprechende Markierungen ersetzt, die von anderen Middlewares untersucht werden können.

# Duplizierte Elemente auflösen

Diese Middleware wird zur Optimierung verwendet, um zu verhindern, dass Elemente in demselben Synchronisierungslauf mehrfach synchronisiert werden.

Information

Das Worst Case Szenario ist die Verwendung des Deltamodus (nur Differenzen abrufen) und die angeschlossenen Systeme listen dann jedes Element für jede Änderung mehrfach auf.

Wenn zum Beispiel ein Artikel seit der letzten Synchronisierung 100 Änderungen erhalten hat, könnte das System diesen Artikel 100 Mal auflisten.

Dies würde zu mindestens 100 Synchronisierungen dieses Elements führen (von denen 99 unnötig wären).

# Anzahl-Limit beachten

Diese Middleware erzwingt das konfigurierte Entry-Limit für einen Sync-Auftrag.

Wenn kein Limit konfiguriert wurde, tut diese Middleware nichts.

Wenn das konfigurierte Limit erreicht ist, wird automatisch eine Freigabe generiert oder, wenn ein hartes Limit konfiguriert ist, werden alle weiteren Einträge übersprungen.

Solange die Freigabe nicht von einem Benutzer bestätigt wurde, werden alle zusätzlichen Elemente nicht synchronisiert.

Information

Alle Einträge werden aus den Systemen geholt, auch wenn das Limit bereits erreicht ist.

Dies ist erforderlich, um die Gesamtzahl der Einträge genau anzugeben.

# Größen-Limit beachten

Diese Middleware erzwingt die konfigurierte Dateigrößenbegrenzung für synchronisierte Dateien.

Wenn kein Limit konfiguriert wurde, tut diese Middleware nichts.

Für jede Datei, die das konfigurierte Limit überschreitet, wird eine Freigabe generiert oder, wenn ein hartes Limit konfiguriert ist, wird die Datei nicht synchronisiert.

Solange die Freigabe nicht von einem Benutzer erteilt wurde, wird die Datei nicht synchronisiert.

# Elemente klassifizieren

Diese Middleware stellt sicher, dass die Zustandsklassifizierung von Gegenständen korrekt ist, oder bestimmt ihren Zustand, wenn er unbekannt ist.

Ähnlich wie die Verknüpfte Elemente behandeln wird diese Middleware verwendet, um sicherzustellen, dass spätere Middlewares einen konsistenten Zustand für alle synchronisierten Items haben.

Diese Middleware hat die folgenden Aufgaben:

  • Sicherstellen, dass neu erstellte Objekte als neu markiert werden
  • Sicherstellen, dass geänderte Elemente tatsächlich als geändert markiert sind
  • Sicherstellen, dass nicht geänderte Elemente tatsächlich als nicht geändert gekennzeichnet sind

# Unterschiede zwischen Elementen herausfinden

Diese Middleware führt den Großteil der Analyse während der Synchronisierung durch.

Es wird ermittelt, welche Änderungen an Elementen vorgenommen wurden und ob diese Änderungen mit anderen Änderungen in Konflikt stehen.

Zunächst wird aus allen verbundenen Elementen ein Prototyp ermittelt.

Dieser Prototyp wird als Vergleichsvorlage für alle anderen Elemente verwendet.

Dann holt es alle Felder aus dem Prototyp und ermittelt dann für jedes Feld die verbundenen Felder.

Jeder Feldeintrag wird dann auf Änderungen geprüft, und wenn nötig und möglich, werden die Inhalte verglichen.

Wenn es keine in Konflikt stehenden Änderungen gibt, wird ein entsprechendes Objekt erstellt, das die spätere Bearbeitung der Änderung ermöglicht. Das Modifikationsobjekt enthält alle erforderlichen Informationen für die Durchführung der Änderung.

Wenn es mehrere, sich in Konflikt stehende Änderungen an verschiedenen Feldern gibt, wird ein Konflikt erzeugt. Es wird ein neuer Konflikt mit allen relevanten Daten erstellt, einschließlich der Elemente und Felder, die von diesem Konflikt betroffen sind.

# Konflikte lösen

Diese Middleware wird verwendet, um Konflikte zu bearbeiten und sie aufzulösen.

Wenn ein Handler einen Konflikt auflösen kann, wird eine entsprechende Modifikation erstellt und mit den anderen Änderungen in eine Warteschlange gestellt.

Wenn kein Handler eine Lösung anbieten kann, wird der Konflikt in das technische Log geschrieben und die Synchronisierung dieses Eintrags abgebrochen, um sicherzustellen, dass keine fehlerhaften Änderungen vorgenommen werden.

# Nicht-destruktive Änderungen anwenden

Diese Middleware führt die eigentliche Synchronisation durch, nachdem alle Analysen abgeschlossen sind.

Diese Middleware wird zu mehreren Stufen hinzugefügt und führt je nach Stufe unterschiedliche Änderungsarten aus.

Die tatsächliche Ausführung von Änderungen wird an die registrierten Change-Handler delegiert, die ihrerseits Änderungen für spätere Phasen verschieben oder sogar ausstehende Änderungen in der aktuellen Phase neu anordnen können.

Die derzeit registrierten Handler haben das folgende Verhalten:

  • In der Standard-Stage werden alle Änderungen, mit Ausnahme von Löschungen, direkt ausgeführt. Die Ausführungsreihenfolge richtet sich nach dem Intra-Entry-Staging der Änderungen, das zuvor von den Analyse-Middlewares festgelegt wurde.
  • Alle destruktiven Änderungen werden für die Ausführung in der Lösch-Stage erneut eingeplant.
  • In der Lösch-Stage werden alle verbleibenden geplanten Änderungen ausgeführt.
Zuletzt aktualisiert: 7. Februar 2025 um 08:28