Fecha
2026-07-13
Estado
Implementado (v1.54.1)
Problema
Regresión del import Visio: los stencils de Cisco (Catalyst 9000) no se renderizan tras la importación. Causa: Cisco incrusta el arte en formato EMF (Enhanced Metafile, nativo de Windows), y libvisio-ng lo envuelve en un <image href="data:image/emf"> que los navegadores web no saben pintar. Del fichero real de Catalyst 9000 (40 MB), 165/165 masters son solo-EMF. Reporte en PROD por Edu el 2026-07-13.
Impacto UX: miniaturas rotas en el modal de stenciles, stencil en el editor muestra icono de imagen rota.
Opciones consideradas
1. Renderizar EMF en el navegador (rechazado)
- No existe soporte estándar de EMF en navegadores modernos.
- Requeriría biblioteca JavaScript pesada (>500 KB) o conversión server-side.
- SVGs compatibles existen, mejor invertir en conversión.
2. Mostrar placeholder en lugar del master (rechazado)
- Peor UX: el usuario importa un stencil esperando imágenes, ve placeholder.
- Confusión: ¿es un error importable? ¿Se debe volver a intentar?
- No aprovecha que el arte está ahí (incrustado).
3. Conversión EMF → PNG en el servidor [ELEGIDA]
Detectar automáticamente stencils solo-EMF y convertirlos a PNG durante el import. Ventajas:
- Transparente para el usuario.
- Aprovecha herramientas existentes (LibreOffice, rsvg).
- No requiere cambios en el cliente.
- Rendimiento aceptable: LibreOffice en lote (~1-2 min para 165 masters).
Decisión
Detección
Función svg_is_emf_only(svg_text):
- Busca patrón
data:image/emf;base64,. - Verifica ausencia de etiquetas vectoriales (
<path>,<rect>, etc.). - Solo SVGs que cumplan AMBAS condiciones se procesan (no tocar vectoriales de verdad).
Conversión con dos capas
Lote 1: EMF → SVG vectorial (alta calidad)
- LibreOffice en modo headless convierte EMF a SVG.
- Una invocación por lote (arranque de LO es el coste principal).
- Resultado: SVG vectorial que rsvg puede rasterizar sin pérdida.
Rasterizado: SVG → PNG (2400 px)
rsvg-converta 2400 px de ancho (nítido en modal, escalable).- Timeout 120 s por operación.
Lote 2: EMF → PNG directo (fallback, menor calidad)
- Si rsvg falló, LibreOffice convierte EMF→PNG (menor escala).
- Una sola invocación por lote para fallidos.
- Mejor que nada; mantiene el usuario informado.
Postproceso
- Blanco → transparente (ImageChops, operación C, no por píxel).
- Autocrop por alpha.
- Escalado mínimo (800 px) si cabe (evita stencils diminutos).
Desaprobación
- Un master solo-EMF cuya conversión falle (lotes 1 y 2) se descarta con warning en logs.
- Mejor ausente que roto: una miniatura rota en el modal es peor UX que su ausencia + nota en logs.
Rationale
-
Tres pasos de conversión (EMF→SVG→PNG + fallback):
- Maximiza calidad (SVG→PNG es sin pérdida de geometría).
- Cubre fallidos (EMF→PNG directo nunca falla, aunque con menor resolución).
- No usa timeouts infinitos (120 s por rsvg, 600 s total).
-
Un lote por operación:
- LibreOffice: arranque una sola vez (costo amortizado entre 165 masters).
- Sin profiler/paralelización: secuencial, pero tolerable (<2 min).
-
Postproceso en C (Pillow):
- Versión anterior usaba loop por píxel; QA PR 3 descubrió OOM con shapes altos (1+ MB de píxeles).
- ImageChops opera en C, sin materializar buffers intermedios.
-
Desaprobación vs. reintento:
- Una conversión que falla probablemente indica corrupción de datos o timeout.
- Reintentar no aporta: o hay bug (reintento infinito) o es una excepción genuina.
- Descartar = operación atomica, no ambigua.
-
Memoria en dev (512M → 1024M):
- libvisio_ng pica ~515 MB de RSS.
- Kernel OOM-killaba con 512M (además, el techo ya mordía a mypy, AUDIT s215).
- PROD no limita; dev sigue siendo aislado.
Alternativas rechazadas
- No convertir: masters rotos.
- Convertir TODO a PNG (incluso vectoriales): pérdida de escala, archivos mayores.
- Usar ImageMagick: libvisio_ng es más sencillo y LibreOffice ya está en el container.
- Deferencia a aplicación cliente: HTML5 Canvas, etc. — requeriría cambios en UI, más LOC, más bugs.
Impacto
Positivo
- Stencils de Cisco (y otros fabricantes con EMF) ahora renderizables.
- Verificación visual: Catalyst 9200/9300 nítidos.
- Regresión resuelta en producción.
Negativo
- Consumo de memoria y CPU durante conversión (mitigado con timeout y guardia de memoria en QA).
- Stencils rotos pre-fix no auto-reparados (re-importación soluciona).
Restricciones futuras
- Ficheros >100 MB puede que no coquen (memoria).
- EMF corrompido o con formatos raros: fallará y se descartará (aceptable).
Testing
- Unit: detección de SVG solo-EMF, conversión mock, descarte de fallidos.
- Integration: flujo end-to-end con Catalyst 9000 real (165 masters, 40 MB).
- QA: opt-in
QA_VISIO=1, guardia de memoria <900 MB.
Véase también
- [[feature—stencils—visio-emf-to-png]]
- [[entity—racks—service—emf-converter]]
- [[entity—racks—function—svg-is-emf-only]]
- [[incident—20260713—cisco-catalyst-stencils-broken]]