Arquitectura del Pipeline
Este documento describe la arquitectura del pipeline, que usa un Grafo Acíclico Dirigido (DAG) para orquestar la generación de artefactos. El pipeline transforma datos de diseño crudos en salidas finales para visualización y manufactura, con programación consciente de dependencias y caché eficiente de artefactos.
Conceptos Core
Nodos de Artefacto y el Grafo de Dependencias
El pipeline usa un Grafo Acíclico Dirigido (DAG) para modelar artefactos y
sus dependencias. Cada artefacto se representa como un ArtifactNode en el
grafo.
ArtifactNode
Cada nodo contiene:
- ArtifactKey: Un identificador único que consiste en un ID y un tipo de
grupo (
workpiece,step,job, oview) - Dependencias: Lista de nodos de los que este nodo depende (hijos)
- Dependientes: Lista de nodos que dependen de este nodo (padres)
Los nodos no almacenan estado directamente. En su lugar, delegan lecturas y
escrituras de estado al ArtifactManager, que mantiene un registro de todos
los artefactos y sus estados.
Estados de Nodo
Los nodos progresan a través de cinco estados:
| Estado | Descripción |
|---|---|
DIRTY | El artefacto necesita ser (re)generado |
PROCESSING | Una tarea está generando actualmente el artefacto |
VALID | El artefacto está listo y actualizado |
ERROR | La generación falló |
CANCELLED | La generación fue cancelada; se reintentará si aún se necesita |
Cuando un nodo se marca como sucio, todos sus dependientes también se marcan como sucios, propagando la invalidación hacia arriba en el grafo.
PipelineGraph
El PipelineGraph se construye desde el modelo Doc y contiene:
- Un nodo para cada par
(WorkPiece, Step) - Un nodo para cada Step
- Un nodo para el Job
Las dependencias se establecen:
- Los Steps dependen de sus nodos de par
(WorkPiece, Step) - El Job depende de todos los Steps
DagScheduler
El DagScheduler es el orquestador central del pipeline. Es dueño del
PipelineGraph y es responsable de:
- Construir el grafo desde el modelo Doc
- Identificar nodos listos (DIRTY con todas las dependencias VALID)
- Disparar lanzamiento de tareas a través de las etapas apropiadas del pipeline
- Rastrear estado a través del proceso de generación
- Notificar consumidores cuando los artefactos están listos
El scheduler trabaja con IDs de generación para rastrear qué artefactos pertenecen a qué versión del documento, permitiendo reuso de artefactos válidos a través de generaciones.
Comportamientos clave:
- Cuando el grafo se construye, el scheduler sincroniza estados de nodo con el artifact manager para identificar artefactos cacheados que pueden reusarse
- Los artefactos de la generación anterior pueden reusarse si permanecen válidos
- Las invalidaciones se rastrean incluso antes de reconstruir el grafo y se vuelven a aplicar después
- El scheduler delega la creación real de tareas a las etapas pero controla cuándo se lanzan las tareas basándose en la disponibilidad de dependencias
ArtifactManager
El ArtifactManager sirve tanto como caché como fuente única de verdad para
el estado de los artefactos. Este:
- Almacena y recupera handles de artefactos mediante un registro (indexado
por
ArtifactKey+ ID de generación) - Rastrea estado (
DIRTY,VALID,ERROR, etc.) en entradas del registro - Gestiona conteo de referencias para limpieza de memoria compartida
- Maneja ciclo de vida (creación, retención, liberación, poda)
- Proporciona gestores de contexto para adopción segura de artefactos, reporte de finalización, fallo y cancelación
GenerationContext
Cada ciclo de reconciliación crea un GenerationContext que rastrea todas
las tareas activas para esa generación. Asegura que los recursos de memoria
compartida permanezcan válidos hasta que todas las tareas en vuelo de una
generación hayan completado, incluso si una generación más nueva ya ha
comenzado. Cuando un contexto es reemplazado y todas sus tareas finalizan,
libera automáticamente sus recursos.
Ciclo de Vida de Memoria Compartida
Los artefactos se almacenan en memoria compartida
(multiprocessing.shared_memory) para comunicación eficiente entre procesos
worker y el proceso principal. El ArtifactStore gestiona el ciclo de vida
de estos bloques de memoria.
Patrones de Propiedad
Propiedad Local: El proceso creador es dueño del handle y lo libera cuando termina. Este es el patrón más simple.
Entrega Entre Procesos: Un worker crea un artefacto, lo envía al proceso principal via IPC, y transfiere propiedad. El worker "olvida" el handle (cierra su descriptor de archivo sin desvincular la memoria), mientras el proceso principal lo "adopta" y se hace responsable de su eventual liberación.
Detección de Artefactos Obsoletos
El mecanismo StaleGenerationError previene que artefactos de generaciones
reemplazadas sean adoptados. Cuando una generación más nueva ha comenzado, el
manager detecta artefactos obsoletos durante la adopción y los descarta
silenciosamente.
Etapas del Pipeline
Las etapas del pipeline (WorkPiecePipelineStage, StepPipelineStage,
JobPipelineStage) son responsables de la mecánica de ejecución de tareas:
- Crean y registran tareas de subproceso mediante el
TaskManager - Manejan eventos de tareas (fragmentos progresivos, resultados intermedios)
- Gestionan adopción de artefactos y caché al completar tareas
- Emiten señales para notificar al pipeline de cambios de estado
El DagScheduler decide cuándo activar cada etapa, pero las etapas manejan el lanzamiento real de subprocesos, manejo de eventos y adopción de resultados.
Estrategia de Invalidación
La invalidación es provocada por cambios al modelo Doc, con diferentes estrategias dependiendo de qué cambió:
| Tipo de Cambio | Comportamiento |
|---|---|
| Geometría/parámetros | Pares workpiece-step invalidados, en cascada a steps y job |
| Posición/rotación | Steps invalidados directamente (en cascada a job); workpieces omitidos a menos que sean sensibles a posición |
| Cambio de tamaño | Igual que geometría: cascada completa desde pares workpiece-step hacia arriba |
| Configuración de máquina | Todos los artefactos forzados a invalidación en todas las generaciones |
Los steps sensibles a posición (ej., aquellos con recorte-a-stock habilitado) provocan invalidación de workpiece incluso para cambios puros de posición.
Desglose Detallado
Entrada
El proceso comienza con el Modelo Doc, que contiene:
- WorkPieces: Elementos de diseño individuales (SVGs, imágenes) colocados en el lienzo
- Steps: Instrucciones de procesamiento (Contour, Raster, etc.) con ajustes
- Layers: Agrupación de workpieces, cada uno con su propio flujo de trabajo
Core del Pipeline
Pipeline (Orquestador)
La clase Pipeline es el director de alto nivel que:
- Escucha al modelo Doc para cambios mediante señales
- Agrupa cambios (200ms de retardo de reconciliación, 50ms de retardo de eliminaci ón)
- Coordina con el DagScheduler para disparar regeneración
- Gestiona el estado de procesamiento general y detección de ocupado
- Soporta pausar/reanudar para operaciones por lotes
- Soporta modo manual (
auto_pipeline=False) donde el recálculo se activa explícitamente en lugar de automáticamente - Conecta señales entre componentes y las retransmite a los consumidores
DagScheduler
El DagScheduler:
- Construye y mantiene el
PipelineGraph - Identifica nodos listos para procesamiento
- Dispara lanzamiento de tareas mediante los métodos
launch_task()de las etapas - Rastrea transiciones de estado de nodo a través del registro
- Emite señales cuando los artefactos están listos
ArtifactManager
El ArtifactManager:
- Mantiene un registro de objetos
LedgerEntry, cada uno rastreando un handle, ID de generación y estado de nodo - Cachea handles de artefactos en memoria compartida
- Gestiona conteo de referencias para limpieza
- Proporciona búsqueda por ArtifactKey e ID de generación
- Poda generaciones obsoletas para mantener el registro limpio
GenerationContext
Cada reconciliación crea un nuevo GenerationContext que:
- Rastrea tareas activas mediante keys con conteo de referencias
- Es dueño de recursos de memoria compartida para su generación
- Se apaga automáticamente cuando es reemplazado y todas las tareas completan
Generación de Artefactos
WorkPieceArtifacts
Generados para cada combinación (WorkPiece, Step). Contiene:
- Toolpaths (
Ops) en el sistema de coordenadas local del workpiece - Flag de escalabilidad y dimensiones fuente para ops independientes de resolución
- Sistema de coordenadas y metadatos de generación
Secuencia de procesamiento:
- Productor: Crea toolpaths crudos (
Ops) desde los datos del workpiece - Transformadores: Modificaciones por workpiece aplicadas en fases ordenadas (Refinamiento de Geometría → Interrupción de Trayectoria → Post Procesamiento)
Los workpieces raster grandes se procesan incrementalmente en fragmentos, permitiendo retroalimentación visual progresiva durante la generación.
StepOpsArtifacts
Generados para cada Step, consumiendo todos los WorkPieceArtifacts relacionados:
- Ops combinadas para todos los workpieces en coordenadas de espacio-mundo
- Transformadores por-step aplicados (Optimize, Multi-Pass, etc.)
JobArtifact
Generado bajo demanda cuando se necesita G-code, consumiendo todos los StepOpsArtifacts:
- Código de máquina final (G-code o formato específico del controlador)
- Ops completas para simulación y reproducción
- Estimación de tiempo de alta fidelidad y distancia total
- Ops mapeadas rotacionalmente para vista previa 3D
Capa de Vista 2D (Separada)
El ViewManager está desacoplado del pipeline de datos. Maneja el
renderizado para el lienzo 2D basándose en el estado de la UI:
RenderContext
Contiene los parámetros de vista actuales:
- Píxeles por milímetro (nivel de zoom)
- Offset del viewport (pan)
- Opciones de visualización (mostrar movimientos de viaje, etc.)
WorkPieceViewArtifacts
El ViewManager crea WorkPieceViewArtifacts que:
- Rasterizan WorkPieceArtifacts a espacio de pantalla
- Aplican el RenderContext actual
- Son cacheados y actualizados cuando el contexto o la fuente cambia
Ciclo de Vida
- ViewManager rastrea handles de
WorkPieceArtifactfuente - Cuando el contexto de renderizado cambia, ViewManager dispara re-renderizado
- Cuando el artefacto fuente cambia, ViewManager dispara re-renderizado
- El re-renderizado está limitado por throttling (intervalo de 33ms) y concurrencia limitada
- La composición progresiva de fragmentos proporciona actualizaciones visuales incrementales
El ViewManager indexa vistas por (workpiece_uid, step_uid) para soportar
visualización de estados intermedios de un workpiece a través de múltiples
steps.
Capa 3D / Simulador (Separada)
El sistema de visualización 3D y simulación está desacoplado del pipeline de datos, siguiendo un patrón similar al ViewManager. Consiste en:
- Un Compilador de Escena que se ejecuta en un subproceso para convertir
las ops del
JobArtifacten datos de vértices listos para GPU - Un OpPlayer que reproduce las ops del trabajo para simulación en tiempo real de la máquina con controles de reproducción
Ambos consumen el JobArtifact producido por la etapa de job del pipeline.
CompiledSceneArtifact
El Compilador de Escena produce un CompiledSceneArtifact que contiene:
- Capas de vértices: Buffers de vértices powered/travel/zero-power con offsets por comando para revelado progresivo
- Capas de textura: Mapas de potencia de líneas de escaneo rasterizados para vista previa de grabado
- Capas de superposición: Segmentos de potencia de líneas de escaneo para resaltado en tiempo real
- Soporte para geometría rotacional (envuelta en cilindro)
Pipeline de Compilación
- Canvas3D escucha señales de
job_generation_finished - Cuando un nuevo job está listo, programa la compilación de escena en un subproceso
- El subproceso lee el
JobArtifactdesde memoria compartida y compila las ops en datos de vértices GPU - La escena compilada se adopta de vuelta en memoria compartida y se sube a los renderizadores GPU
OpPlayer (Backend del Simulador)
El OpPlayer recorre las ops del trabajo comando por comando, manteniendo un
MachineState que rastrea posición, estado del láser y ejes auxiliares. Esto
impulsa:
- La reproducción del lienzo 3D (revelado progresivo de la trayectoria)
- Posición de la cabeza de la máquina y visualización del haz láser
- Avance por comando para el control deslizante de reproducción
Consumidores
| Consumidor | Usa | Propósito |
|---|---|---|
| Lienzo 2D | WorkPieceViewArtifacts | Renderiza workpieces en espacio de pantalla |
| Lienzo 3D | CompiledSceneArtifact | Renderiza trabajo completo en 3D con reproducción |
| Máquina | JobArtifact (código de máquina) | Salida de manufactura |
Decisiones Arquitectónicas Clave
-
Programación basada en DAG: En lugar de etapas secuenciales, los artefactos se generan a medida que sus dependencias se vuelven disponibles, permitiendo paralelismo.
-
Estado basado en registro: El estado del nodo se rastrea en las entradas del registro del ArtifactManager en lugar de en los nodos del grafo, proporcionando una fuente única de verdad tanto para estado como para almacenamiento de handles.
-
Separación de Capa de Vista: Tanto el lienzo 2D (ViewManager) como el lienzo 3D (Compilador de Escena) están desacoplados del pipeline de datos. Cada uno ejecuta su propio renderizado basado en subprocesos y es impulsado por señales del pipeline en lugar de ser parte del DAG.
-
IDs de Generación: Los artefactos se rastrean con IDs de generación, permitiendo reuso eficiente a través de versiones de documento y detección de artefactos obsoletos.
-
Orquestación Centralizada: El DagScheduler es el punto único de control para programación de tareas; las etapas manejan la mecánica de ejecución.
-
Aislamiento de GenerationContext: Cada generación tiene su propio contexto, asegurando que los recursos permanezcan vivos hasta que todas las tareas en vuelo completen.
-
Rastreo de Invalidación: Las keys marcadas como sucias antes de reconstruir el grafo se preservan y se vuelven a aplicar después de la reconstrucción.
-
Reconciliación con Debounce: Los cambios se agrupan con retardos configurables para evitar ciclos excesivos del pipeline durante ediciones rápidas.