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
staticque 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.