Arquitectura
Arquitectura
Sección titulada «Arquitectura»Wippy es un sistema de capas construido en Go. Los componentes se inicializan en orden de dependencias, se comunican a través de un event bus, y ejecutan procesos Lua vía un scheduler de work-stealing.
| Capa | Componentes |
|---|---|
| Application | Procesos Lua, funciones, workflows |
| Runtime | Motor Lua (gopher-lua), 50+ módulos |
| Services | HTTP, Queue, Storage, Temporal |
| System | Topology, Factory, Functions, Contracts |
| Core | Scheduler, Registry, Dispatcher, EventBus, Relay |
| Infrastructure | AppContext, Logger, Transcoder |
Cada capa depende solo de capas debajo de ella. La capa Core proporciona primitivos fundamentales, mientras Services construye abstracciones de nivel más alto encima.
Secuencia de Boot
Sección titulada «Secuencia de Boot»El startup de la aplicación procede a través de cuatro fases.
Fase 1: Infraestructura
Sección titulada «Fase 1: Infraestructura»Crea infraestructura core antes de que cualquier componente cargue:
| Componente | Propósito |
|---|---|
| AppContext | Diccionario sellado para referencias de componentes |
| EventBus | Pub/sub para comunicación entre componentes |
| Transcoder | Serialización de payload (JSON, YAML, Lua) |
| Logger | Logging estructurado con streaming de eventos |
| Relay | Routing de mensajes (Node, Router, Mailbox) |
Fase 2: Carga de Componentes
Sección titulada «Fase 2: Carga de Componentes»El Loader resuelve dependencias vía ordenamiento topológico y carga componentes nivel por nivel. Componentes en el mismo nivel cargan en paralelo.
Los componentes core (PIDGen, Dispatcher, Registry, Finder, Supervisor) se inicializan primero, seguidos por los componentes de sistema (Topology, Lifecycle, Factory, Functions, Contracts). Los niveles concretos se calculan en tiempo de ejecución a partir del grafo de dependencias, por lo que el orden se adapta a medida que se añaden o eliminan componentes.
Cada componente se adjunta al contexto durante Load, haciendo servicios disponibles a componentes dependientes.
Fase 3: Activación
Sección titulada «Fase 3: Activación»Después de que todos los componentes cargan:
- Freeze Dispatcher - Bloquea registry de handlers de comandos para lookups sin lock
- Seal AppContext - No más escrituras permitidas, habilita lecturas sin lock
- Start Components - Llama
Start()en cada componente con interfazStarter
Fase 4: Carga de Entradas
Sección titulada «Fase 4: Carga de Entradas»Las entradas de registry (de archivos YAML) son cargadas y validadas:
- Entradas parseadas de archivos de proyecto
- Etapas de pipeline transforman entradas (override, link, bytecode)
- Servicios marcados
auto_start: truecomienzan a ejecutar - Supervisor monitorea servicios registrados
Componentes
Sección titulada «Componentes»Los componentes son servicios Go que participan en el ciclo de vida de la aplicación.
Fases de Ciclo de Vida
Sección titulada «Fases de Ciclo de Vida»| Fase | Método | Propósito |
|---|---|---|
| Load | Load(ctx) (ctx, error) | Inicializar y adjuntar al contexto |
| Start | Start(ctx) error | Comenzar operación activa |
| Stop | Stop(ctx) error | Apagado graceful |
Los componentes declaran dependencias. El loader construye un grafo acíclico dirigido y ejecuta en orden topológico. El shutdown ocurre en orden reverso.
Componentes Estándar
Sección titulada «Componentes Estándar»| Componente | Dependencias | Propósito |
|---|---|---|
| PIDGen | ninguna | Generación de ID de proceso |
| Dispatcher | PIDGen | Despacho de handlers de comandos |
| Registry | Dispatcher | Almacenamiento y versionado de entradas |
| Finder | Registry | Lookup y búsqueda de entradas |
| Supervisor | Registry | Políticas de reinicio de servicios |
| Topology | Supervisor | Árbol padre/hijo de procesos |
| Lifecycle | Topology | Gestión de ciclo de vida de servicios |
| Factory | Lifecycle | Generación de procesos |
| Functions | Factory | Llamadas a funciones stateless |
Event Bus
Sección titulada «Event Bus»Pub/sub asíncrono para comunicación entre componentes.
- Una sola goroutine dispatcher procesa todos los eventos
- Entrega de acciones basada en cola previene bloqueo de publishers
- Pattern matching soporta tópicos exactos y wildcards (
*) - Ciclo de vida basado en contexto vincula suscripciones a cancelación
Flujo de Eventos
Sección titulada «Flujo de Eventos»sequenceDiagram participant P as Publisher participant B as EventBus participant S as Subscribers
P->>B: Publish(topic, data) B->>B: Match patterns B->>S: Queue action S->>S: Execute callbackTópicos Comunes
Sección titulada «Tópicos Comunes»Los tópicos tienen el formato <system>:<kind>. Los sistemas integrados publican:
| Sistema | Kind | Propósito |
|---|---|---|
registry | entry.create, entry.update, entry.delete, entry.accept, entry.reject | Mutaciones de entradas |
registry | registry.begin, registry.commit, registry.discard | Límites de transacción |
process | factory.register, factory.delete, factory.accept, factory.reject | Registro de factory para tipos de proceso |
supervisor | service.register, service.remove, service.update, service.start, service.stop | Ciclo de vida de servicio |
Registry
Sección titulada «Registry»Almacenamiento versionado para definiciones de entradas.
Características
Sección titulada «Características»- Versioned State - Cada mutación crea nueva versión
- History - Historial respaldado por SQLite para audit trail
- Observation - Watch de entradas específicas para cambios
- Event-driven - Publica eventos en mutaciones
Ciclo de Vida de Entrada
Sección titulada «Ciclo de Vida de Entrada»flowchart LR YAML[YAML Files] --> Parser Parser --> Stages[Pipeline Stages] Stages --> Registry Registry --> Validation Validation --> ActiveEtapas de pipeline transforman entradas:
| Etapa | Propósito |
|---|---|
| Override | Aplicar overrides de config |
| Disable | Remover entradas por patrón |
| Link | Resolver requirements y dependencias |
| Bytecode | Compilar Lua a bytecode |
| EmbedFS | Recolectar entradas de filesystem |
Routing de mensajes entre procesos a través de nodos.
Routing de Tres Niveles
Sección titulada «Routing de Tres Niveles»flowchart LR subgraph Router Local[Local Node] --> Peer[Peer Nodes] Peer --> Inter[Internode] end
Local -.- L[Mismo proceso] Peer -.- P[Mismo cluster] Inter -.- I[Remoto]- Local - Entrega directa dentro del mismo nodo
- Peer - Forward a nodos peer en cluster
- Internode - Enrutar a nodos remotos vía red
Mailbox
Sección titulada «Mailbox»Cada nodo tiene un mailbox con pool de workers:
- Hashing FNV-1a asigna remitentes a workers
- Preserva ordenamiento de mensajes por remitente
- Workers procesan mensajes concurrentemente
- Back-pressure cuando cola se llena
AppContext
Sección titulada «AppContext»Diccionario sellado para referencias de componentes.
| Propiedad | Comportamiento |
|---|---|
| Before seal | Escrituras de un solo hilo durante el arranque |
| After seal | Lecturas sin lock, panic en escritura |
| Duplicate keys | Panic |
| Type safety | Funciones getter tipadas |
Los componentes adjuntan servicios durante fase Load. Después de que boot completa, AppContext es sellado para rendimiento óptimo de lectura.
Shutdown
Sección titulada «Shutdown»El apagado graceful procede en orden reverso de dependencias:
- SIGINT/SIGTERM dispara shutdown
- Supervisor detiene servicios gestionados
- Componentes con interfaz
StopperrecibenStop() - Limpieza de infraestructura
Segunda señal fuerza salida inmediata.
Ver También
Sección titulada «Ver También»- Scheduler - Ejecución de procesos
- Event Bus - Sistema pub/sub
- Registry - Gestión de estado
- Command Dispatch - Manejo de yields