Decisión Estratégica — Stack Backend dkv-pet-flows¶
Tipo: ADR (Architecture Decision Record)
Estado: 🔴 REQUIERE DECISIÓN
Impacto: Alto — afecta a toda la implementación backend
Decisores: Lead Developer + DevOps + CTO
1. Contexto¶
dkv-pet-cloud (fuente de verdad) usa Spring Boot + Apache Pekko (fork de Akka) con:
- Actor system con persistence (event_journal, snapshot, durable_state)
- Cache distribuido Pekko para staging
- Sistema de mensajería real-time (STOMP + RabbitMQ)
- 3 backenders aprendiendo esta tecnología ahora mismo
Para dkv-pet-flows se exploró Quarkus + Dapr + LangChain4j, stack completamente diferente. Hay que decidir el camino.
2. Las tres opciones¶
graph TD
subgraph "Opción A: Continuista"
A["Spring Boot + Pekko<br/>Mismo stack que dkv-pet-cloud"]
end
subgraph "Opción B: Cloud-Native Puro"
B["Quarkus + Dapr<br/>Stack optimizado para K8s"]
end
subgraph "Opción C: Híbrido Pragmático"
C["Quarkus + Dapr<br/>Escalado horizontal K8s nativo<br/>Microservicio independiente"]
end
A -->|"Equipo unificado<br/>1 stack"| TEAM["👥 3 Backenders"]
B -->|"Stack nuevo<br/>2 stacks"| TEAM
C -->|"Aislado<br/>no afecta learning curve"| TEAM
style A fill:#059669,color:#fff
style B fill:#7C3AED,color:#fff
style C fill:#D97706,color:#fff
3. Comparativa técnica exhaustiva¶
Performance y Cloud-Native¶
| Criterio | Spring Boot + Pekko | Quarkus + Dapr |
|---|---|---|
| Startup JVM | ~2.5s | ~0.8s (2x más rápido) |
| Startup nativo | ⚠️ Problemático con Pekko | ~40ms (12x más rápido) |
| Memoria JVM | ~200-400MB | ~100-200MB |
| Memoria nativo | No viable con Pekko | ~30-50MB |
| Throughput (req/s) | ≈ Comparable | ≈ Comparable |
| K8s pod density | Menor (más RAM) | Mayor (menos RAM) |
| Scale-to-zero | Inviable (2.5s startup) | Viable (40ms nativo) |
Complejidad del código (DX)¶
| Aspecto | Spring Boot + Pekko | Quarkus + Dapr |
|---|---|---|
| REST endpoint | Controller + Service + ActorRef | @Path + @Inject (CDI) |
| Persistencia | JPA/Hibernate + Pekko Persistence | Panache (1 línea = CRUD) |
| Workflow | Pekko Actors manuales + FSM | Dapr Workflow SDK (declarativo) |
| Config | application.yaml (569 líneas) | application.properties (simple) |
| Boilerplate | Alto (actor messages, props, supervision trees) | Bajo (annotations, CDI injection) |
| Complejidad visual | 🔴 Alta — actores, mensajes tipados, supervision | 🟢 Baja — imperativo, familiar |
| Learning curve | 🔴 Alta (Pekko es paradigma diferente) | 🟢 Baja (similar a JAX-RS / Spring MVC) |
Compilación nativa (GraalVM)¶
| Aspecto | Spring Boot + Pekko | Quarkus |
|---|---|---|
| Soporte oficial | ⚠️ Pekko NO garantiza native | ✅ Core feature de Quarkus |
| Reflection | 🔴 "Reflection hell" — nkpacket, serialización actores | ✅ Build-time processing |
| Clases inesperadas | 🔴 Fallan en runtime, difícil detectar en CI | ✅ Detectado en build time |
| Pipeline CI | Requiere tests exhaustivos para detectar clases | Tests estándar suficientes |
| Imagen final | ~150-200MB (JVM) | ~30MB (nativo) |
[!WARNING] Confirmado por investigación: La compilación nativa con Pekko es "ir contranatura". GraalVM asume un "closed-world" pero Pekko usa reflexión masiva, class loading dinámico, y serialización de actores. Cualquier clase no registrada falla silenciosamente en runtime.
4. Perspectiva del equipo — Factor humano¶
Situación actual¶
| Persona | Stack actual | Nivel Pekko | Nivel Quarkus |
|---|---|---|---|
| Lead Dev (tú) | Pekko + Quarkus | 🟢 Alto | 🟢 Alto |
| DevOps | Infraestructura | 🟡 N/A | 🟡 N/A (pero prefiere cloud-native) |
| Backend 1 | Aprendiendo dkv-pet-cloud | 🔴 Aprendiendo | 🔴 Desconocido |
| Backend 2 | Aprendiendo dkv-pet-cloud | 🔴 Aprendiendo | 🔴 Desconocido |
| Backend 3 | Aprendiendo dkv-pet-cloud | 🔴 Aprendiendo | 🔴 Desconocido |
Impacto por opción¶
| Factor | Opción A (Pekko) | Opción B/C (Quarkus) |
|---|---|---|
| Cognitive load | ✅ Un solo paradigma | ⚠️ Dos paradigmas distintos |
| Transferencia de skills | ✅ Lo aprendido en PET-Cloud sirve | ❌ Skills no transferibles |
| Riesgo de burnout | ✅ Bajo | ⚠️ Medio-alto si son 3 devs junior |
| AI-assisted coding | 🟡 Pekko es menos "spec-codeable" | ✅ Quarkus es muy amigable a IA |
| Onboarding | 🟡 Python → actores = difícil | ✅ Quarkus parece "Spring simplificado" |
| Code reviews | 🟡 Actor code es opaco | ✅ Código imperativo legible |
5. Perspectiva de negocio¶
| Factor | Opción A | Opción B/C |
|---|---|---|
| Time-to-market | ⚠️ Más lento (Pekko learning curve alta) | ✅ Más rápido si Lead Dev lo implementa |
| Mantenibilidad | ⚠️ Solo el Lead Dev entiende profundamente | ✅ Todo el equipo puede mantener |
| Riesgo bus factor | 🔴 Alto — si Lead Dev no está, nadie mantiene | ✅ Bajo — Quarkus es más accesible |
| Go-live julio | ✅ No afecta dkv-pet-cloud | ✅ No afecta dkv-pet-cloud |
| Coste operativo K8s | 🟡 Más pods = más RAM | ✅ Menos RAM por pod |
6. ¿Es realmente necesario Pekko para los FSMs de los Flows?¶
[!IMPORTANT] Cada flow ES una FSM — nodos = estados, edges = transiciones, condiciones = eventos. La pregunta no es "¿necesitamos FSM?" (sí). La pregunta es: ¿FSM estático (Pekko) o FSM dinámico (Dapr Workflows)?
Análisis completo en: Análisis FSM — Flows como Máquinas de Estados
| Aspecto | Pekko FSM | Dapr Workflows |
|---|---|---|
| Tipo de FSM | Estático (estados en compilación) | Dinámico (estados en JSON) |
| 40 tipos de nodo | 40 message types + handlers | 40 Activity classes |
| Combinaciones del usuario | 🔴 State explosion | ✅ Grafo interpretado |
| Event sourcing | Manual (Pekko Persistence) | Automático (built-in) |
| Durabilidad ante crash | Manual (~500 líneas extra) | Nativo (0 código) |
| DX | Actor messages, Props, supervision | Código imperativo, familiar |
Conclusión: Los flows de Pet Flows son FSMs dinámicos — el usuario los diseña visualmente. Dapr Workflows está construido exactamente para este patrón. Pekko FSM brilla para FSMs con estados conocidos en compilación (ej: OrderStatus).
7. Recomendación: Opción C — Híbrido Pragmático¶
graph LR
subgraph "dkv-pet-cloud"
PC["Spring Boot<br/>+ Pekko Actors<br/>(Equipo aprende aquí)"]
end
subgraph "dkv-pet-flows"
PF["Quarkus<br/>+ Dapr Workflows<br/>(Microservicio aislado)"]
end
subgraph "Shared"
DB["PostgreSQL<br/>(schemas separados)"]
K8S["Kubernetes"]
end
PC <-->|"REST API<br/>JSON/HTTP"| PF
PC --> DB
PF --> DB
PC --> K8S
PF --> K8S
style PC fill:#059669,color:#fff
style PF fill:#7C3AED,color:#fff
style DB fill:#2563EB,color:#fff
style K8S fill:#D97706,color:#fff
¿Por qué Opción C?¶
-
No impacta la learning curve del equipo. Los 3 backenders siguen aprendiendo Pekko en dkv-pet-cloud — no se les pide aprender Quarkus ahora.
-
El Lead Dev (tú) y DevOps lideran Pet Flows. Quarkus + Dapr es manejable para vosotros dos. Cuando el equipo domine Pekko en PET-Cloud, pueden gradualmente acercarse a Pet Flows.
-
Microservicio verdaderamente independiente. Pet Flows se comunica con dkv-pet-cloud via REST API — no necesita compartir actor system, clustering, ni sharding.
-
Nativo de verdad. Pet Flows compila a native sin los problemas de "reflection hell" de Pekko.
-
El código es dramáticamente más simple. Code reviews más fáciles, onboarding futuro más rápido.
-
Dapr cubre lo que Pekko haría. Event sourcing, state management, workflow orchestration — todo built-in en Dapr sin actor model.
Escalado horizontal — Completamente soportado¶
[!IMPORTANT] Quarkus + Dapr escala horizontalmente de forma nativa en Kubernetes. No necesita actor clustering porque K8s ya proporciona esa capacidad.
graph LR
subgraph "Kubernetes Cluster"
HPA["HPA\nHorizontal Pod Autoscaler"]
subgraph "Réplica 1"
PF1["Quarkus Pod"]
DS1["Dapr Sidecar"]
end
subgraph "Réplica 2"
PF2["Quarkus Pod"]
DS2["Dapr Sidecar"]
end
subgraph "Réplica N"
PFN["Quarkus Pod"]
DSN["Dapr Sidecar"]
end
DAPR_PLACE["Dapr Placement Service\nDistribuye workflows"]
end
subgraph "Estado compartido"
PG["PostgreSQL"]
REDIS["Redis\nDapr State Store"]
end
HPA --> PF1 & PF2 & PFN
DS1 & DS2 & DSN --> DAPR_PLACE
DS1 & DS2 & DSN --> PG & REDIS
style HPA fill:#D97706,color:#fff
style DAPR_PLACE fill:#7C3AED,color:#fff
| Mecanismo | Cómo funciona |
|---|---|
| K8s HPA | Auto-escala pods basado en CPU/memoria/métricas custom |
| Dapr Placement | Distribuye workflow instances entre pods disponibles |
| Dapr State Store | Estado compartido via Redis/PostgreSQL (no en memoria local) |
| Quarkus nativo (40ms) | Pods arrancan instantáneamente ante picos de demanda |
| Stateless pods | Cualquier pod puede atender cualquier request |
Riesgo principal y mitigación¶
| Riesgo | Mitigación |
|---|---|
| "Dos stacks = fragmentación" | Pet Flows es un microservicio independiente — la frontera es clara |
| "El equipo no puede mantenerlo" | Quarkus es más fácil que Pekko. La barrera de entrada es MENOR, no mayor |
| "¿Y si necesitamos actor model?" | Dapr Workflows = actor model simplificado (mismos patrones, menos ceremonia) |
8. Plan de transición de conocimiento¶
FASE ACTUAL (ahora):
└── 3 Backenders → aprenden Pekko en dkv-pet-cloud
└── Lead Dev + DevOps → construyen Pet Flows en Quarkus
FASE 2 (post go-live julio):
└── 3 Backenders ya dominan Pekko
└── Lead Dev introduce Quarkus en Tech Talks internas
└── 1 Backend voluntario hace PR pequeño en Pet Flows
FASE 3 (Q4 2026):
└── Equipo completo puede mantener ambos stacks
└── Decisión informada: ¿consolidar en un stack o mantener dos?
9. Matriz de decisión final¶
| Criterio (peso) | A: Spring+Pekko | C: Quarkus+Dapr |
|---|---|---|
| Cloud-native (20%) | 6/10 | 10/10 |
| DX / simplicidad (15%) | 4/10 | 9/10 |
| Team capacity (25%) | 7/10 (un stack) | 8/10 (aislado, no impacta) |
| Performance K8s (15%) | 6/10 | 9/10 |
| Compilación nativa (10%) | 2/10 | 10/10 |
| Mantenibilidad (15%) | 5/10 | 8/10 |
| TOTAL PONDERADO | 5.4 | 9.0 |
Documentos Relacionados¶
| Nivel | Documento |
|---|---|
| Plan | Implementation Plan Backend |
| Auditoría | dkv-notifications |
| Spike | Dapr Workflows |
| Arquitectura | Arquitectura del Sistema |