2 minute read

Tras las recientes integraciones visuales en el entorno de desarrollo, esta semana el trabajo se ha centrado en mejorar la arquitectura del código, aplicando buenas prácticas de desarrollo en React. El objetivo principal ha sido resolver un problema de acoplamiento lógico relacionado con la sonda de salida (exit_exercise) y el ciclo de vida del ejercicio.

Inicialmente, la lógica encargada de detectar cuándo el alumno abandonaba el entorno (al cerrar la pestaña o cambiar de página) se encontraba alojada en el componente visual de la cabecera. Aunque funcional, esto rompía el principio de Responsabilidad Única (Separation of Concerns), delegando tareas de conexión con el backend a un componente que debería ser estrictamente visual.

Archivos involucrados

  • Frontend: AcademyProjects.tsx y ExerciseHeader.tsx.

El problema del acoplamiento y la solución arquitectónica

La reestructuración se ha llevado a cabo moviendo la lógica de comunicación con la API desde los componentes de la interfaz de usuario hacia el componente principal que actúa como controlador de la vista. Los cambios clave se dividen en los siguientes puntos:

  1. Centralización del ciclo de vida: El componente principal de la ruta (AcademyProjects.tsx) ya disponía de un manejador de eventos para ejecutar la función exitProject() al desmontarse la vista o al saltar el evento pagehide del navegador. Para centralizar toda la lógica de salida, se ha trasladado aquí la llamada a sendExecutionProbe(data.exercise_id, "exit_exercise").
  2. Sincronización de peticiones: Al agrupar ambas llamadas dentro de la misma función handleUnload, garantizamos que la limpieza del proyecto en el frontend y el registro telemétrico en el backend a través de la sonda ocurran de manera estrictamente síncrona. Esto elimina posibles condiciones de carrera (race conditions) o envíos duplicados al servidor.
  3. Limpieza del componente visual: En ExerciseHeader.tsx se ha eliminado por completo el useEffect encargado de la monitorización de cierre, así como la importación de las peticiones a la API. Ahora, este componente es “tonto” (dumb component) en lo que respecta al ciclo de vida global de la página.
  4. Mantenimiento de los controles interactivos: Las acciones que dependen de una interacción manual explícita del usuario, como los botones de Play, Pause, Reset o Terminate, se han mantenido dentro de ExerciseHeader.tsx (en el subcomponente ExecutionControl). Esta es su ubicación natural, ya que responden a eventos de clic (onClick) directos sobre la interfaz y no a comportamientos automáticos del navegador.

Además se ha modificado el tiempo de espera para considerar que un alumno ha dejado de escribir dentro del ejercicio. Se ha pasado de 5 segundos a 1 minuto.