Pipeline-Architektur
Dieses Dokument beschreibt die Pipeline-Architektur, die einen Gerichteten Azyklischen Graphen (DAG) verwendet, um die Artefaktgenerierung zu orchestrieren. Die Pipeline transformiert Roh-Designdaten in finale Ausgaben für Visualisierung und Fertigung, mit abhängigkeitsbewusster Planung und effizientem Artefakt-Caching.
Kernkonzepte
Artefakt-Nodes und der Abhängigkeitsgraph
Die Pipeline verwendet einen Gerichteten Azyklischen Graphen (DAG), um Artefakte und
ihre Abhängigkeiten zu modellieren. Jedes Artefakt wird als ArtifactNode im
Graphen repräsentiert.
ArtifactNode
Jeder Node enthält:
- ArtifactKey: Ein eindeutiger Bezeichner, bestehend aus einer ID und einem Gruppentyp
(
workpiece,step,joboderview) - Dependencies: Liste von Nodes, von denen dieser Node abhängt (Kinder)
- Dependents: Liste von Nodes, die von diesem Node abhängen (Eltern)
Nodes speichern keinen Zustand direkt. Stattdessen delegieren sie Lese- und
Schreibzugriffe auf den Zustand an den ArtifactManager, der ein Register aller Artefakte
und ihrer Zustände verwaltet.
Node-Zustände
Nodes durchlaufen fünf Zustände:
| Zustand | Beschreibung |
|---|---|
DIRTY | Das Artefakt muss (neu) generiert werden |
PROCESSING | Eine Task generiert gerade das Artefakt |
VALID | Das Artefakt ist bereit und aktuell |
ERROR | Generierung fehlgeschlagen |
CANCELLED | Generierung wurde abgebrochen; wird bei Bedarf erneut versucht |
Wenn ein Node als dirty markiert wird, werden auch alle seine Dependents als dirty markiert, was die Invalidierung den Graph hinauf propagiert.
PipelineGraph
Der PipelineGraph wird aus dem Doc-Modell erstellt und enthält:
- Einen Node für jedes
(WorkPiece, Step)-Paar - Einen Node für jeden Step
- Einen Node für den Job
Abhängigkeiten werden hergestellt:
- Steps hängen von ihren
(WorkPiece, Step)-Paar-Nodes ab - Job hängt von allen Steps ab
DagScheduler
Der DagScheduler ist der zentrale Orchestrator der Pipeline. Er besitzt den
PipelineGraph und ist verantwortlich für:
- Aufbau des Graphen aus dem Doc-Modell
- Identifizierung bereiter Nodes (DIRTY mit allen VALIDEN Abhängigkeiten)
- Starten von Tasks über die entsprechenden Pipeline-Stufen
- Zustandsverfolgung während des Generierungsprozesses
- Benachrichtigung von Konsumenten, wenn Artefakte bereit sind
Der Scheduler arbeitet mit Generierungs-IDs, um zu verfolgen, welche Artefakte zu welcher Dokumentversion gehören, was die Wiederverwendung gültiger Artefakte über Generationen hinweg ermöglicht.
Wichtige Verhaltensweisen:
- Wenn der Graph aufgebaut wird, synchronisiert der Scheduler Node-Zustände mit dem Artefakt-Manager, um zwischengespeicherte Artefakte zu identifizieren, die wiederverwendet werden können
- Artefakte aus der vorherigen Generation können wiederverwendet werden, wenn sie gültig bleiben
- Invalidierungen werden sogar vor Graph-Neuaufbau verfolgt und danach erneut angewendet
- Der Scheduler delegiert die tatsächliche Task-Erstellung an die Stufen, kontrolliert aber wann Tasks gestartet werden, basierend auf der Bereitschaft der Abhängigkeiten
ArtifactManager
Der ArtifactManager dient sowohl als Cache als auch als einzige Wahrheitsquelle
für den Artefaktzustand. Er:
- Speichert und ruft Artefakt-Handles über ein Register ab (indiziert durch
ArtifactKey+ Generierungs-ID) - Verfolgt Zustände (
DIRTY,VALID,ERROR, usw.) in Registereinträgen - Verwaltet Referenzzählung für Shared-Memory-Cleanup
- Behandelt Lebenszyklus (Erstellung, Zurückhaltung, Freigabe, Bereinigung)
- Bietet Kontextmanager für sichere Artefaktadoption, Abschluss, Fehler- und Abbruchmeldung
GenerationContext
Jeder Abgleichszyklus erstellt einen GenerationContext, der alle
aktiven Tasks für diese Generation verfolgt. Er stellt sicher, dass Shared-Memory-Ressourcen
gültig bleiben, bis alle laufenden Tasks einer Generation abgeschlossen sind,
auch wenn bereits eine neuere Generation gestartet wurde. Wenn ein Kontext
abgelöst wird und alle seine Tasks beendet sind, gibt er seine
Ressourcen automatisch frei.
Shared-Memory-Lebenszyklus
Artefakte werden in Shared Memory (multiprocessing.shared_memory) gespeichert für
effiziente Inter-Prozess-Kommunikation zwischen Arbeitsprozessen und dem Hauptprozess. Der ArtifactStore verwaltet den Lebenszyklus dieser Speicherblöcke.
Eigentumsmuster
Lokales Eigentum: Der erstellende Prozess besitzt den Handle und gibt ihn frei, wenn er fertig ist. Dies ist das einfachste Muster.
Inter-Prozess-Übergabe: Ein Worker erstellt ein Artefakt, sendet es an den Hauptprozess via IPC und überträgt das Eigentum. Der Worker "vergisst" den Handle (schließt seinen Dateideskriptor ohne den Speicher zu unlinken), während der Hauptprozess ihn "adoptiert" und für die eventuelle Freigabe verantwortlich wird.
Erkennung veralteter Artefakte
Der StaleGenerationError-Mechanismus verhindert, dass Artefakte aus abgelösten
Generationen adoptiert werden. Wenn eine neuere Generation gestartet wurde, erkennt
der Manager veraltete Artefakte während der Adoption und verwirft sie stillschweigend.
Pipeline-Stufen
Die Pipeline-Stufen (WorkPiecePipelineStage, StepPipelineStage,
JobPipelineStage) sind für die Mechanik der Task-Ausführung verantwortlich:
- Sie erstellen und registrieren Unterprozess-Tasks über den
TaskManager - Sie behandeln Task-Ereignisse (progressive Chunks, Zwischenergebnisse)
- Sie verwalten Artefaktadoption und Caching nach Task-Abschluss
- Sie emittieren Signale, um die Pipeline über Zustandsänderungen zu benachrichtigen
Der DagScheduler entscheidet, wann jede Stufe ausgelöst wird, aber die Stufen behandeln das tatsächliche Spawnen von Unterprozessen, die Ereignisbehandlung und die Ergebnisadoption.
Invalidierungsstrategie
Invalidierung wird durch Änderungen am Doc-Modell ausgelöst, mit verschiedenen Strategien je nachdem, was sich geändert hat:
| Änderungstyp | Verhalten |
|---|---|
| Geometrie/Parameter | Workpiece-Step-Paare invalidiert, kaskadiert zu Steps und Job |
| Position/Drehung | Steps direkt invalidiert (kaskadiert zu Job); Workpieces übersprungen außer positionsempfindlich |
| Größenänderung | Wie Geometrie: vollständige Kaskade von Workpiece-Step-Paaren aufwärts |
| Maschinenkonfiguration | Alle Artefakte force-invalidiert über alle Generationen |
Positionsempfindliche Steps (z.B. solche mit aktiviertem Crop-to-Stock) lösen Workpiece-Invalidierung sogar bei reinen Positionsänderungen aus.
Detaillierte Aufschlüsselung
Eingabe
Der Prozess beginnt mit dem Doc Model, das enthält:
- WorkPieces: Einzelne Design-Elemente (SVGs, Bilder), die auf der Canvas platziert sind
- Steps: Verarbeitungsanweisungen (Kontur, Raster, usw.) mit Einstellungen
- Layers: Gruppierung von Workpieces, jede mit eigenem Workflow
Pipeline-Kern
Pipeline (Orchestrator)
Die Pipeline-Klasse ist der übergeordnete Dirigent, der:
- Hört über Signale auf Änderungen am Doc-Modell
- Entprellt Änderungen (200ms Abgleichsverzögerung, 50ms Entfernungsverzögerung)
- Koordiniert mit dem DagScheduler, um Neugenerierung auszulösen
- Verwaltet den gesamten Verarbeitungsstatus und Beschäftigt-Erkennung
- Unterstützt Pause/Fortsetzen für Stapelverarbeitungen
- Unterstützt Manuellen Modus (
auto_pipeline=False), bei dem Neuberechnung explizit statt automatisch ausgelöst wird - Verbindet Signale zwischen Komponenten und leitet sie an Konsumenten weiter
DagScheduler
Der DagScheduler:
- Baut und wartet den
PipelineGraph - Identifiziert zur Verarbeitung bereite Nodes
- Startet Tasks über die
launch_task()-Methoden der Stufen - Verfolgt Node-Zustandsübergänge über das Register
- Emittiert Signale, wenn Artefakte bereit sind
ArtifactManager
Der ArtifactManager:
- Verwaltet ein Register aus
LedgerEntry-Objekten, die jeweils einen Handle, Generierungs-ID und Node-Zustand verfolgen - Cacht Artefakt-Handles in Shared Memory
- Verwaltet Referenzzählung für Cleanup
- Bietet Lookup nach ArtifactKey und Generierungs-ID
- Bereinigt veraltete Generationen, um das Register sauber zu halten
GenerationContext
Jeder Abgleich erstellt einen neuen GenerationContext, der:
- Aktive Tasks über referenzzählende Schlüssel verfolgt
- Shared-Memory-Ressourcen für seine Generation besitzt
- Sich automatisch herunterfährt, wenn abgelöst und alle Tasks abgeschlossen sind
Artefaktgenerierung
WorkPieceArtifacts
Generiert für jede (WorkPiece, Step)-Kombination. Enthält:
- Werkzeugwege (
Ops) im lokalen Koordinatensystem des Workpieces - Skalierbarkeits-Flag und Quelldimensionen für auflösungsunabhängige Ops
- Koordinatensystem und Generierungsmetadaten
Verarbeitungssequenz:
- Produzent: Erstellt rohe Werkzeugwege (
Ops) aus den Workpiece-Daten - Transformatoren: Pro-Workpiece-Modifikationen, angewendet in geordneten Phasen (Geometrieverfeinerung → Pfadunterbrechung → Nachbearbeitung)
Große Raster-Workpieces werden inkrementell in Chunks verarbeitet, was progressives visuelles Feedback während der Generierung ermöglicht.
StepOpsArtifacts
Generiert für jeden Step, konsumiert alle zugehörigen WorkPieceArtifacts:
- Kombinierte Ops für alle Workpieces in Weltkoordinaten
- Pro-Step-Transformatoren angewendet (Optimieren, Mehrfach-Durchgang, usw.)
JobArtifact
Generiert auf Anfrage, wenn G-Code benötigt wird, konsumiert alle StepOpsArtifacts:
- Finaler Maschinencode (G-Code oder treiberspezifisches Format)
- Vollständige Ops für Simulation und Wiedergabe
- Hochpräzise Zeitschätzung und Gesamtdistanz
- Rotary-abbildende Ops für 3D-Vorschau
2D-Ansichtsebene (Getrennt)
Der ViewManager ist entkoppelt von der Daten-Pipeline. Er behandelt
Rendering für die 2D-Canvas basierend auf dem UI-Zustand:
RenderContext
Enthält die aktuellen Ansichtsparameter:
- Pixel pro Millimeter (Zoom-Stufe)
- Viewport-Offset (Pan)
- Anzeigeoptionen (Positionierbewegungen anzeigen, usw.)
WorkPieceViewArtifacts
Der ViewManager erstellt WorkPieceViewArtifacts, die:
- WorkPieceArtifacts in den Bildschirmraum rastern
- Den aktuellen RenderContext anwenden
- Zwischengespeichert und aktualisiert werden, wenn sich Kontext oder Quelle ändern
Lebenszyklus
- ViewManager verfolgt Quell-
WorkPieceArtifact-Handles - Wenn sich der Renderkontext ändert, löst ViewManager Neu-Rendering aus
- Wenn sich das Quellartefakt ändert, löst ViewManager Neu-Rendering aus
- Neu-Rendering ist gedrosselt (33ms-Intervall) und parallelitätsbeschränkt
- Progressives Chunk-Zusammensetzen bietet inkrementelle visuelle Aktualisierungen
Der ViewManager indiziert Views nach (workpiece_uid, step_uid), um die
Visualisierung von Zwischenzuständen eines Workpieces über mehrere Steps hinweg zu unterstützen.
3D-/Simulatorebene (Getrennt)
Das 3D-Visualisierungs- und Simulationssystem ist entkoppelt von der Daten-Pipeline und folgt einem ähnlichen Muster wie der ViewManager. Es besteht aus:
- Einem Scene Compiler, der in einem Unterprozess läuft, um
JobArtifact-Ops in GPU-fertige Vertexdaten umzuwandeln - Einem OpPlayer, der die Ops des Jobs für eine Echtzeit-Maschinen- simulation mit Wiedergabesteuerung abspielt
Beide konsumieren das JobArtifact, das von der Job-Stufe der Pipeline erzeugt wird.
CompiledSceneArtifact
Der Scene Compiler erzeugt ein CompiledSceneArtifact, das enthält:
- Vertex-Ebenen: Powered/Travel/Zero-Power-Vertexpuffer mit pro-Befehl-Offsets für progressive Enthüllung
- Textur-Ebenen: Rasterisierte Scanline-Leistungskarten für Gravur-Vorschau
- Overlay-Ebenen: Scanline-Leistungssegmente für Echtzeit-Hervorhebung
- Unterstützung für Rotary-Geometrie (zylindergewickelt)
Kompilierungs-Pipeline
- Canvas3D hört auf
job_generation_finished-Signale - Wenn ein neuer Job bereit ist, plant es die Szenenkompilierung in einem Unterprozess
- Der Unterprozess liest das
JobArtifactaus dem Shared Memory und kompiliert Ops in GPU-Vertexdaten - Die kompilierte Szene wird zurück in den Shared Memory adoptiert und auf GPU-Renderer hochgeladen
OpPlayer (Simulator-Backend)
Der OpPlayer durchläuft die Ops des Jobs Befehl für Befehl und pflegt
einen MachineState, der Position, Laserzustand und Hilfsachsen verfolgt.
Dies steuert:
- Die 3D-Canvas-Wiedergabe (progressive Enthüllung des Werkzeugwegs)
- Maschinenkopfposition und Laserstrahl-Visualisierung
- Pro-Befehl-Schrittweite für den Wiedergabe-Slider
Konsumenten
| Konsument | Verwendet | Zweck |
|---|---|---|
| 2D Canvas | WorkPieceViewArtifacts | Rendert Workpieces im Bildschirmraum |
| 3D Canvas | CompiledSceneArtifact | Rendert vollständigen Job in 3D mit Wiedergabe |
| Maschine | JobArtifact (Maschinencode) | Fertigungsausgabe |
Wichtige Architekturentscheidungen
-
DAG-basierte Planung: Statt sequenzieller Stufen werden Artefakte generiert, sobald ihre Abhängigkeiten verfügbar werden, was Parallelität ermöglicht.
-
Register-basierter Zustand: Node-Zustand wird in den Registereinträgen des ArtifactManagers statt in den Graph-Nodes selbst verfolgt, was eine einzige Wahrheitsquelle für sowohl Zustand als auch Handle-Speicherung bietet.
-
Ansichtsebenen-Trennung: Sowohl die 2D-Canvas (ViewManager) als auch die 3D-Canvas (Scene Compiler) sind von der Daten-Pipeline entkoppelt. Jede betreibt ihr eigenes unterprozessbasiertes Rendering und wird durch Pipeline- Signale gesteuert, anstatt Teil des DAG zu sein.
-
Generierungs-IDs: Artefakte werden mit Generierungs-IDs verfolgt, was effiziente Wiederverwendung über Dokumentversionen und Erkennung veralteter Artefakte ermöglicht.
-
Zentralisierte Orchestrierung: Der DagScheduler ist der einzelne Kontrollpunkt für Task-Planung; Stufen behandeln die Mechanik der Ausführung.
-
GenerationContext-Isolation: Jede Generation hat ihren eigenen Kontext, was sicherstellt, dass Ressourcen lebendig bleiben, bis alle laufenden Tasks abgeschlossen sind.
-
Invalidierungs-Tracking: Als dirty markierte Schlüssel vor Graph-Neuaufbau werden bewahrt und nach Neuaufbau erneut angewendet.
-
Entprellter Abgleich: Änderungen werden mit konfigurierbaren Verzögerungen gebündelt, um übermäßige Pipeline-Zyklen bei schnellen Bearbeitungen zu vermeiden.