Skip to content

vladimiracunadev-create/problem-driven-systems-lab

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

70 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🧪 Problem-Driven Systems Lab

License: MIT Docker PHP Node.js Python Java .NET Status

Portafolio técnico orientado a problemas reales de software: rendimiento, observabilidad, resiliencia, arquitectura y continuidad operacional. Este repositorio forma parte del ecosistema público de Vladimir Acuña y traduce esa narrativa en escenarios ejecutables, documentados y honestos sobre su madurez real.

🎯 Executive Summary

  • El laboratorio modela 12 problemas reales de ingeniería, utilizando fallos de alta fidelidad inyectados (I/O, Memoria, Excepciones) en lugar de simulaciones abstractas.
  • Los casos 01 al 12 son piezas de ingeniería operativa en PHP, Python, Node.js, Java 21 y .NET 8 con primitivas nativas distintas por lenguaje (ConcurrentHashMap/ConcurrentDictionary, CompletableFuture.orTimeout/CancellationTokenSource, LinkedHashMap LRU/Dictionary+LinkedList, record types, Optional<T>/?.+??, Semaphore/SemaphoreSlim, ThreadPoolExecutor/ThreadPool.GetAvailableWorkerThreads saturation observable, etc.). El stack PHP incluye UI nativa para diagnósticos visuales.
  • Implementa patrones profesionales (Adapter, Strangler, Circuit Breaker, LRU, Cancellation) resolviendo cuellos de botella reales en cada runtime.
  • Docker es la vía oficial de ejecución limpia y reproducible.
  • shared/catalog/cases.json es la fuente de verdad del portal, de la documentacion generada y de la narrativa operativa.
  • El portal raiz ahora sirve como hub de evaluacion: rutas por audiencia, seleccion por lenguaje, proof cards y probes server-side.
  • ☁️ Plan de despliegue en la nube documentado en AWS_MIGRATION.md: tres rutas (ECS Fargate, Lambda, EKS), costos reales estimados, paso a paso, y un mapping explicito de como AWS mitiga cada hallazgo del SECURITY.md (auth via Cognito, rate limiting via WAF, atomicidad via DynamoDB, etc.) sin tocar codigo del lab.

💻 Interfaz Visual Integrada

El laboratorio no es solo una "API JSON ciega". Los 12 casos en PHP ahora interceptan solicitudes HTTP de navegadores (mediante cabeceras Accept) y devuelven Dashboards Interactivos. Esto permite a reclutadores, líderes y desarrolladores ver cómo se bloquea una base de datos, cómo aumentan las latencias, y probar escenarios en vivo usando estéticas modernas sin afectar el núcleo programático.

💡 Que demuestra este producto

Area Evidencia concreta
Diagnostico tecnico Cada caso parte desde sintomas, causas, trade-offs y solucion esperada
Ejecucion reproducible Cada stack mantiene Dockerfile y compose.yml propios
Operacion realista Los casos operativos no son demos vacias: usan DB, worker, metricas, logs o trazas segun corresponda
Claridad para audiencias mixtas El portal y la documentacion separan rutas para recruiter, liderazgo tecnico, developer y beginner
Honestidad tecnica Se distingue explicitamente entre OPERATIVO y DOCUMENTADO / SCAFFOLD

🧭 Como evaluarlo rapido

Perfil Punto de entrada Que deberia poder concluir
Recruiter / hiring manager RECRUITER.mddocs/executive-summary.md El repo deja evidencia real y los 12 casos caben en una pagina ejecutiva
CTO / Head of Engineering ARCHITECTURE.md Hay criterio sistemico, foco en operacion y reduccion de riesgo
Developer / DevOps INSTALL.mdRUNBOOK.md El entorno levanta limpio y los casos operativos cuentan una historia tecnica verificable
Security engineer SECURITY.md Modelo de amenaza explicito, hallazgos del analisis interno y frontera honesta entre lo que el lab garantiza y lo que no
Beginner docs/BEGINNERS_GUIDE.md La estructura y la taxonomia de madurez son comprensibles antes de entrar al codigo

Si quieres una sola puerta de entrada local con los 12 casos PHP disponibles, levanta docker compose -f compose.root.yml up -d --build y abre http://localhost:8080.

🏷️ Madurez actual

Nivel Significado
OPERATIVO Caso resolviendo el problema de forma real, con Docker y evidencia observable
DOCUMENTADO / SCAFFOLD Caso bien modelado, con estructura y docs listas, pero sin la misma profundidad funcional todavia
PLANIFICADO Futuro del roadmap, aun no presente en el arbol actual

Estado actual:

  • OPERATIVO en PHP: todos los casos 01 al 12, con UI nativa, Prometheus, Grafana y fallos de alta fidelidad.
  • OPERATIVO en Python: los 12 casos, con logica funcional equivalente a PHP, stdlib pura y autocontenidos en un solo contenedor.
  • OPERATIVO en Node.js: los 12 casos, con primitivas Node-especificas distintas por caso (event loop lag, SQLite real via node:sqlite built-in en caso 02, AbortController, AbortSignal.timeout, process.memoryUsage(), Map<consumer, handler> strangler, Proxy de compatibilidad, EventEmitter, monitorEventLoopDelay, optional chaining como runbook codificado).
  • OPERATIVO en Java 21: los 12 casos, con primitivas JDK-distintas por caso: ConcurrentHashMap summary cache + ScheduledExecutorService worker (01), SQLite real via sqlite-jdbc + PreparedStatement + batch IN(?, ...) (02), ThreadLocal<RequestContext> correlation (03), CompletableFuture.orTimeout + AtomicReference<BreakerState> CAS (04), LinkedHashMap.removeEldestEntry LRU + Runtime metrics (05), record types + state machine (06), ConcurrentHashMap<String,Function> routing mutable (07), Function proxy + CopyOnWriteArrayList<Consumer> event bus (08), Semaphore budget + snapshot cache + AtomicReference breaker (09), HashMap O(1) vs N hops StringBuilder (10), ThreadPoolExecutor.getActiveCount() saturation observable + ExecutorService dedicado (11), Optional<T> + map/orElse como runbook codificado (12).
  • OPERATIVO en .NET 8: los 12 casos, con primitivas BCL-distintas por caso: ConcurrentDictionary summary cache + Task.Delay worker con CancellationToken (01), SQLite real via Microsoft.Data.Sqlite + SqliteCommand + batch IN(@id0, ...) (02), AsyncLocal<RequestContext> para correlation_id en pipeline async (03), CancellationTokenSource con timeout + breaker Interlocked CAS (04), LRU manual con Dictionary + LinkedList + Process.WorkingSet64 (05), ConcurrentDictionary<string,EnvState> + máquina de estados con rollback automático (06), Func<Request,Response> delegate routing + record types (07), ImmutableList<Action<string>> + Func<Old,New> proxy con cutover gradual (08), MemoryCache/ConcurrentDictionary snapshot + SemaphoreSlim budget + Interlocked.CompareExchange breaker (09), lookup directo Dictionary vs N hops JsonSerializer con presión LOH (10), ConcurrentExclusiveSchedulerPair o Thread dedicado + ThreadPool.GetAvailableWorkerThreads (11), ?./?? con Nullable Reference Types como runbook codificado en el sistema de tipos (12).

🔐 Postura de seguridad y modelo de despliegue

El lab está pensado para correr en localhost. Esa decisión define toda su postura de seguridad — y este repo prefiere ser explícito sobre eso antes que vender una robustez que no implementa.

Escenario Riesgo realista Recomendado
Localhost only (docker compose up en tu máquina) Bajo — el atacante necesita acceso físico o ya está dentro ✅ caso de uso pensado
LAN / VM con 0.0.0.0 Medio — cualquiera del segmento puede llamar /reset-lab, intentar DoS ⚠️ requiere reverse proxy con auth
Internet sin proxy con auth Alto/Crítico — sin auth, sin rate limiting, sin TLS ❌ no exponer así

Lo que el código sí garantiza (verificado por revisión manual): SQL injection bloqueada por prepared statements, validación por allowlist de scenarios/consumers, regex allowlist en SKU/release, clamping numérico en todos los enteros de query, paths fijos sin user input (sin path traversal), spawn de subprocesos con paths fijos del registry (sin RCE), crypto.randomBytes para IDs impredecibles, sin eval/exec/shell, fallback seguro en JSON.parse de state corrupto, AbortSignal cooperativo en pipelines.

Lo que NO garantiza (intencional, es un lab): autenticación, rate limiting, TLS, validación de método HTTP, headers de seguridad, atomicidad de escrituras de state.

➡️ Análisis completo en SECURITY.md — modelo de amenaza, los 4 hallazgos altos/medios con mitigación concreta, las defensas activas en detalle (con archivo:línea), y el checklist mínimo si necesitás exponerlo más allá de localhost.

🎯 Honestidad de fidelidad (qué es real vs qué es simulado)

El lab declara explicitamente donde el substrato es real y donde es simulado por decision didactica:

Caso PHP Python Node.js Java .NET
02 (N+1) PostgreSQL real SQLite stdlib SQLite node:sqlite SQLite sqlite-jdbc SQLite Microsoft.Data.Sqlite
01 (latencia) PostgreSQL real SQLite stdlib Memoria + setTimeout (simulado) Memoria + sleepMicros (simulado) Memoria + Task.Delay (simulado)

Caso 02 tiene fidelidad universal — los 5 stacks ejecutan N+1 real contra SQL embebido. Caso 01 mantiene asimetria: PHP/Python con contencion real, Node/Java/.NET con substrato simulado pero patron de solucion real (worker concurrente + cache + readers no bloqueados con primitivas idiomaticas genuinas). La asimetria esta documentada en cada comparison.md y en el ROADMAP — "Fidelidad universal de caso 01" como deuda explicita.

🔎 Catálogo de Casos Resolutivos

Caso Comparativa PHP Python Node.js Java 21 .NET 8 Estado Que deja como prueba
01 - API lenta bajo carga ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Latencia legacy vs optimized; metricas Grafana (PHP), event loop lag (Node), ConcurrentHashMap summary cache + worker (Java), ConcurrentDictionary + Task.Delay worker (.NET)
02 - N+1 y cuellos de botella DB ⚖️ 👉 🐍 🟢 🟦 OPERATIVO N+1 vs batch IN(...); db_hits medido en cada stack
03 - Observabilidad deficiente ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Logs opacos vs telemetria util con correlation_id; ThreadLocal<RequestContext> (Java), AsyncLocal<RequestContext> (.NET)
04 - Timeout chain y retry storms ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Retries agresivos vs CB+fallback; AbortController (Node), CompletableFuture.orTimeout (Java), CancellationTokenSource + Interlocked.CompareExchange (.NET)
05 - Presion de memoria y fugas ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Estado retenido vs eviccion; heap V8+RSS (Node), LinkedHashMap LRU (Java), LRU manual Dictionary+LinkedList + Process.WorkingSet64 (.NET)
06 - Pipeline roto y delivery fragil ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Detectar tarde vs preflight+rollback; record types + state machine (Java/.NET), with-expressions para rollback (.NET)
07 - Modernización del Monolito ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Strangler fig; Map<consumer,handler> mutable (Node), ConcurrentHashMap<String,Function> (Java), ConcurrentDictionary<string,Func<Request,Response>> (.NET)
08 - Extracción Crítica Módulo ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Big bang vs extract-and-proxy + cutover; Proxy+EventEmitter (Node), Function proxy + CopyOnWriteArrayList (Java), Func<Old,New> + ImmutableList<Action<string>> event bus (.NET)
09 - Integración Externa Inestable ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Adapter + cache + breaker; AbortSignal.timeout (Node), Semaphore budget (Java), SemaphoreSlim + Interlocked.CompareExchange breaker (.NET)
10 - Arquitectura Sobre-Dimensionada ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Complejo vs right-sized; CPU real en hops JSON (Node), N hops StringBuilder vs HashMap (Java), N hops JsonSerializer con presión LOH vs Dictionary (.NET)
11 - Reportes Pesando la Operación ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Locks vs aislamiento; monitorEventLoopDelay() (Node), ThreadPoolExecutor.getActiveCount() (Java), ConcurrentExclusiveSchedulerPair + ThreadPool.GetAvailableWorkerThreads (.NET)
12 - Single Point of Knowledge ⚖️ 👉 🐍 🟢 🟦 OPERATIVO Bus factor con runbooks; optional chaining ?. (Node), Optional<T> (Java), ?. + ?? con Nullable Reference Types (.NET)

El catalogo completo detallado se genera desde metadatos automatizados y vive en docs/case-catalog.md. Cada caso se sirve mediante un robusto servidor en PHP listo para consumir tanto por UI Web como por API.

🖥️ Portal y experiencia de producto

La raiz del laboratorio ya no es solo una lista de archivos. El portal local ahora cumple cuatro funciones:

  • explica el producto por audiencia;
  • deja elegir lenguaje y ver solo casos realmente operativos;
  • muestra por que importa cada caso y que evidencia deberia verse;
  • ejecuta probes server-side para devolver status code, latencia y ultima verificacion real desde el propio portal.

Esto lo vuelve mucho mas claro para reclutadores, lideres y personas que quieren corroborar rapido si el producto esta vivo y por que importa.

🚀 Inicio rapido

Convención de stacks por lenguaje

Cada lenguaje tiene su propio compose en la raíz del repositorio. Un comando levanta los 12 casos de ese lenguaje. Los stacks son independientes y pueden correr en paralelo sin colisión de puertos.

Archivo Lenguaje Puertos expuestos Estado
compose.root.yml PHP 8.3 8080 portal · 8100 PHP hub · 9091 Prometheus · 3001 Grafana OPERATIVO
compose.python.yml Python 3.12 8200 Python hub OPERATIVO
compose.nodejs.yml Node.js 20 8300 Node hub OPERATIVO
compose.java.yml Java 21 8400 Java hub OPERATIVO
compose.dotnet.yml .NET 8 8500 .NET hub OPERATIVO

Cinco hubs operativos (uno por lenguaje): PHP, Python, Node, Java y .NET sirven los 12 casos cada uno. Un solo puerto por hub vía routing por path (/01/health.../12/health). Los servicios de soporte (DB, Prometheus, Grafana) tienen los suyos propios porque son servicios distintos del lenguaje.

🧱 Los cinco hubs siguen el mismo patrón arquitectónico: un contenedor por lenguaje (pdsl-php-lab, pdsl-python-lab, pdsl-node-lab, pdsl-java-lab, pdsl-dotnet-lab) ejecuta sus 12 casos como subprocesos internos en puertos no expuestos. PHP suma ~7 contenedores extras solo porque los servicios reales que el caso 01 estudia (PostgreSQL, worker, Prometheus, Grafana) son contenedores aparte por necesidad técnica — no son procesos del lenguaje. Detalles, trade-offs y comparación per-case en docs/docker-strategy.md.

# PHP: portal + dispatcher (12 casos internos en un contenedor) + DB + Prometheus + Grafana
docker compose -f compose.root.yml up -d --build

# Python: dispatcher (12 casos internos en un contenedor)
docker compose -f compose.python.yml up -d --build

# Node.js: dispatcher (12 casos internos en un contenedor)
docker compose -f compose.nodejs.yml up -d --build

# Java: dispatcher (12 casos internos en un contenedor)
docker compose -f compose.java.yml up -d --build

# .NET 8: dispatcher (12 casos internos en un contenedor)
docker compose -f compose.dotnet.yml up -d --build

# Portal liviano solamente
docker compose -f compose.portal.yml up -d --build

Con esto, los 60 endpoints operativos (12 casos × 5 stacks) viven detras de 5 puertos: 8100, 8200, 8300, 8400, 8500. El portal (8080) y la observabilidad (9091 Prometheus, 3001 Grafana) suman 3 mas. 8 puertos cubren el laboratorio entero.

Ejecucion aislada de un solo caso (modo estudio)

Cada caso mantiene su propio compose.yml para reproducir UN problema en aislamiento — util cuando la gracia del caso es el aislamiento (caso 05 mide heap V8 sin contaminacion de otros workloads; caso 11 mide event_loop_lag_ms sin requests concurrentes diluyendo la senal). Para los demas casos, los hubs son suficientes.

# PHP aislado (ejemplo caso 01)
docker compose -f cases/01-api-latency-under-load/php/compose.yml up -d --build

# Python aislado (ejemplo caso 01)
docker compose -f cases/01-api-latency-under-load/python/compose.yml up -d --build

# Node.js aislado (ejemplo caso 11 — para medir event loop lag sin ruido)
docker compose -f cases/11-heavy-reporting-blocks-operations/node/compose.yml up -d --build

Tambien existen atajos con make, pero la ruta soportada y mas portable sigue siendo docker compose directo.

📚 Documentacion del repositorio

Documento Rol
RECRUITER.md Ruta ejecutiva para evaluacion rapida
ARCHITECTURE.md Vista ejecutiva de la arquitectura actual
AWS_MIGRATION.md ☁️ Plan de migracion a AWS (ECS Fargate · Lambda · EKS) con los hubs PHP/Python/Node/Java, costos reales, paso a paso y mapping de hallazgos SECURITY.md → mitigaciones AWS
INSTALL.md Instalacion y puesta en marcha recomendada
RUNBOOK.md Operacion diaria y chequeos iniciales
SECURITY.md Politica de seguridad y reporte responsable
SUPPORT.md Como pedir ayuda y que informacion incluir
CONTRIBUTING.md Reglas para crecer el laboratorio sin degradarlo
CHANGELOG.md Historial notable de cambios
docs/architecture.md Mapa estructural del repositorio
docs/case-catalog.md Catalogo sincronizado desde metadatos
docs/executive-summary.md 📋 Resumen ejecutivo: los 12 casos en una pagina (problema · valor · evidencia)
docs/docker-strategy.md Por que Docker es el modelo operativo oficial
docs/recruiter-guide.md Guia extendida para lectores no tecnicos

🏗️ Arquitectura en una frase

El sistema se organiza como una capa editorial en raiz, un portal de evaluacion con entrada completa PHP o modo liviano, una biblioteca de 12 casos problem-driven y cinco stacks operativos detras de hubs simetricos por lenguaje (PHP/Python/Node/Java/.NET los 12 casos cada uno). La arquitectura completa esta documentada en ARCHITECTURE.md y docs/architecture.md.

🌐 Ecosistema relacionado

✅ Lo que este repo si es

  • Un laboratorio serio para demostrar criterio tecnico transferible.
  • Una base reproducible para conversar de rendimiento, observabilidad y arquitectura.
  • Un portfolio documentado que privilegia problemas reales sobre features aisladas.

🚫 Lo que este repo no vende

  • Paridad multi-stack universal a nivel de feature: los cinco stacks (PHP, Python, Node, Java, .NET) cubren los 12 casos cada uno con primitivas idiomáticas distintas — no es paridad sintáctica, es paridad funcional con criterio por runtime.
  • Benchmarks absolutos entre lenguajes.
  • Seniority inflada con claims sin evidencia.

⚖️ Licencia

El repositorio se publica bajo MIT. Revisa tambien docs/usage-and-scope.md para entender sus limites de uso y la postura honesta del proyecto.

About

🧪 Laboratorio Docker-first con 12 problemas reales de ingeniería resueltos en 5 stacks (PHP · Python · Node.js · Java · .NET): rendimiento, observabilidad, resiliencia, modernización legacy y arquitectura — con evidencia operacional verificable 🐳

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors