====== 11 - La Forja: peticiones que llegan a la vez ====== La API funciona de maravilla... con un usuario. El programa del paso 02 era secuencial: una acción a la vez. Ahora cada petición vive en su **hilo**, y todos los hilos tocan el mismo bean de repositorio. El paso aplica los conceptos del tema: **pool de hilos de Tomcat y estado compartido**. Aquí no se implementa nada: el entregable es un **diagnóstico**. ===== 1. Qué se pide ===== * **Averiguar cómo atiende la app sus peticiones**: qué hilo las recibe, dónde se ve, cuántos hilos da el pool y cuántos se reutilizan. * Diseñar un **experimento** que demuestre el estado compartido: dos o más peticiones que tocan el mismo dato a la vez (el caso clásico: dos registros de héroe solapados) y registrar lo que se observa. * **Diagnosticar** los puntos de la app donde el estado es compartido: qué dato vive solo para un hilo (y por tanto está seguro) y qué dato comparten todos — y qué consecuencia *actual* o *futura* tiene en cada uno. * El entregable es un **informe breve** (los tres puntos anteriores), que se defiende en clase. El código de la app no cambia en este paso: **detectar**, no arreglar. ===== 2. Con qué ===== * El pool de hilos de **Tomcat**: configurado en `application.properties` (mínimo de hilos preparados y máximo del pool) — se ajusta para el experimento si hace falta apurar el diagnóstico. * La observación del log del servidor para ver qué hilo atendió cada petición (`http-nio-8080-exec-N`). * Peticiones **simultáneas** lanzadas en paralelo desde el terminal (`&` y `wait`), varias seguidas y varias a la vez, para comparar. * El recordatorio del tema: dónde vive cada cosa y a quién se comparte: ^ Situación ^ Dónde vive ^ Qué ocurre ^ | variable local de un método | pila del hilo | no se comparte: segura sin esfuerzo | | campo/bean del repositorio | único (singleton) | compartido: todos los hilos leen/escriben lo mismo | | ''ThreadLocal'' | propio del hilo | hay que limpiarlo, porque Tomcat reutiliza el hilo | ===== 3. Decisiones tuyas ===== * ¿Cuántas peticiones y cómo se lanzan para demostrar la reutilización y para demostrar el acceso simultáneo? ¿Y cómo distingues ambas cosas en el log? * ¿Qué dato compartido observas en el experimento y qué estropea cuando se solapan dos peticiones? (El contador de ids del paso 03 es candidato). * El experimento tiene que llegar a intensidad suficiente: si no falla, ¿es que no hay condiciones de carrera o es que el estímulo no da para tanto? * ¿Qué situaciones de La Forja no necesitan control porque su estado es local, y cuáles sí deberían preocuparte? ===== 4. Comprobación ===== * El informe nombra el mecanismo (pool + hilos reutilizables) y muestra la evidencia del log que lo demuestra: misma petición hilo distinto, peticiones seguidas con hilo igual. * El experimento propuesto es reproducible: otro compañero lo lanza y observa algo parecido. * La condición de carrera se explica con la causa: las tres operaciones de que se compone un ''++'' (leer, sumar, guardar) y por qué solapadas producen resultados imposibles (ids repetidos, plantilla inconsistente). * El inventario de estado compartido cubre los puntos de la app: repositorio, contadores, colecciones, cualquier ''static'' que quedara de la historia consola. * El informe separa lo que es problema **hoy** de lo que lo será **cuando llegue el paso 12** — el contexto por petición es un caso aparte. ===== 5. Adelanto ===== El paso 12 realmente necesita **un valor por hilo** (la identidad autenticada de cada petición). Ahí es donde ''ThreadLocal'' —y su limpieza— entra en escena con el modelo correcto.