Arquitectura de Red

La arquitectura de red del sistema es la siguiente:

Como se puede observar en el diagrama, se utilizan dos tipos de sockets (UDP y TCP) para cumplir con tareas bastante distintas.
La comunicación UDP se utiliza para transmitir información de interés entre los terminales. Se utiliza este tipo de sockets por tres razones:
-El overhead de los datagramas es menor (menor header) y se requiere de una comunicación rápida y que no sature la red.
-Permite al software continuar con su tarea facilmente ante cualquier eventualidad con el terminal al otro lado. Si este se desconecta o hay perdidas de paquetes o el host no existe (o no esta corriendo su servidor biogym en él), el software siempre podrá continuar, ya que hay un timeout implementado para esta comunicación.
-La perdida de un paquete no implica ningún problema para el software.
Este tipo de comunicación puede ser iniciado por el software de dos formas: manualmente o automáticamente. En la primera modalidad, el usuario selecciona un host de su lista y le pide que reporte su información. En la otra, una hebra del software se encarga de pedir la información a todos los hosts a intervalos periódicos.
La comunicación TCP se utiliza para enviar todos los datos para realizar un entrenamiento. En este caso un socket TCP es más idóneo, ya que:
-Para esto se requiere de una comunicación en que se asegure que no se perderán paquetes.
-La información en este caso es más delicada y la comunicación más esporádica, por lo que el mayor overhead no es un problema.
Esta comunicación es iniciada por el software cuando el usuario decide enviar una tarea de entrenamiento a un terminal y éste la acepta.

Diagrama de Bloques

Los módulos que son los pilares del sistema son (nótese que estos son los que componen el software en su totalidad y no son instancias aisladas en distintas máquinas):

HostLocal: corresponde a una hebra que hace las veces de servidor. Este servidor se encarga de recibir peticiones mediante UDP y atenderlas (por ejemplo: enviar la información sobre su terminal). También cumple con el rol de servidor ante una transmisión de una tarea de entrenamiento, realizada por comunicación TCP.
Canal de Comunicación: entrega los servicios de comunicación mediante TCP y UDP a los servidores y clientes. Al ser un módulo aparte (incluso se ha incluido en un paquete propio) facilita a los desarrolladores tareas de debugeo, mejoras o cambios, tanto ligeros, como radicales, en la implementación.
Hebra Refrescadora: cuando esta corriendo, permite al sistema actualizar su información sobre los hosts que están en su lista periódicamente, ya que los interroga (les pide información) a intervalos constantes.
Hebra Interrogadora: se encarga de interrogar a los terminales dentro de la lista de hosts (es invocada por el usuario o por la hebra refrescadora).
Motor de Entrenamiento: es el encargado de tomar las peticiones de entrenamiento que lleguen mediante la comunicació:n TCP e iniciar los procesos correspondientes para llevar a cabo el entrenamiento. Se ocupa de comunicar los resultados una vez que un entrenamiento concluye.
Lista de Hosts: Contiene todos los hosts conocidos (que pudiesen estar corriendo biogym), a quienes el sistema interrogará y que, eventualmente, pudiesen atender una petición de entrenamiento.
GUI: simplifica al usuario la tarea de configuración del sistema, como también su operación. Permite, además, desplegar la información sobre los hots y su lista.

Hebras

El siguiente diagrama aclara las hebras presentes en el sistema.

Hebra de GUI: encargada de construir y desplegar todos los componentes de la interfaz gráfica.
Hebra de HostLocal: es la hebra que hace las veces de servidor. Atiende peticiones UDP y transmisiones de tareas de entrenamiento mediante TCP.
Hebra Interrogadora: es la que hace las veces de cliente. Pide a un set de hosts que le entreguen información sobre sus estados (y la recibe).
Hebra Refrescadora: se encarga de crear periódicamente una hebra interrogadora para actualizar la información de todos los terminales en la lista de hosts.
Hebra de Entrenamiento: se encarga de invocar a los procesos correspondientes para realizar una tarea de entrenamiento y se encarga de sus valores de retorno y comunicación de estos al sistema.

La GUI

El sistema cuenta con una serie de herramientas que pueden correrse de forma stand-alone o integradas en una sola ventana. Cuando están en la segunda modalidad, cada herramienta se despliega en una tarjeta distinta (es decir, la ventana tiene una etiqueta para cada herramienta).

El Creador de Host Local

Permite al usuario configurar su servidor local, de manera de elegir en que puerto escuchará por peticiones, cuantos entrenamientos simultaneos podrán realizarse (marcos) y cuantos de estos serán reservados para terminales remotos (marcos remotos). También permite setear los servicios de entrenamiento para los cuales el terminal dará soporte.
Además, permite ver la información sobre el procesador de la máquina.

Información de Host Local

Permite al usuario ver la información sobre los parámetros de su servidor local e iniciarlo.

Administrador de Hosts

Despliega en una tabla la lista de hosts conocidos.
El usuario puede agregar o eliminar hosts de esta lista, como también manejar la forma en que se actualiza la información de estos.
La tabla permite ver todos los datos relevantes sobre un hosts (si no se ha podido comunicar con un host, se le indica también al usuario):

Componer Entrenamiento

Contiene todos los paneles (en forma de tarjetas) que permiten manejar datos y parámetros para realizar un entrenamiento.
Estos paneles pueden venir con biogym, ser desarrolladors por los creadores de biogym o por terceros.
En las primeras versiones de biogym se incluirá un panel para crear entrenamientos para FRUBTANN (reconocedor de caras de bioid), para poder probar el software.

Algunos Detalles Interesantes sobre la Implementación

En esta sección compartimos algunos de los trucos que utiliza biogym para realizar las tareas más importantes.
Debido a que el código es extenso, estimamos que es mejor explicar las soluciones que copiar y pegar líneas de éste.

La comunicación de información

biogym se vale de una herramienta muy útil en java: la serialización.
La serialización permite la persistencia de un objeto dentro de un programa java a través de su almacenamiento en disco duro o una base de datos, como también su trasmisión hacia otra JVM a través de un socket.
Gracias a esto, biogym guarda la información que recibe desde los terminales en un archivo, en forma de objeto. Así cuando se requiere de la información, solamente basta con restituir el objeto desde el archivo.
Algo similar se hace cuando los hosts están transmitiendose información sobre ellos: el host esta reflejado en un objeto, por lo tanto, éste se se serializa y envia al cliente, quien lo restituye como objeto y lo guarda.

El Traspaso del Entrenamiento

Nuevamente nos valemos de la serialización. En este caso, los datos y parámetros para el entrenamiento se envuelven en un objeto y luego éste es serializado y enviado hacia el terminal que se encargará de restituirlo y llevar a cabo el entrenamiento.

Sincronización de Hebras

Las hebras más delicadas son la de la GUI, la refrescadora y la interrogadora.
Algunas de las cosas que podrían ocurrir si no se sincronizan bien son las siguientes (no entraremos en el detalle del porque):
-Un host eliminado de la lista vuelve a aparecer después de una actualización de la tabla.
-Intentos de comunicarse con varios hosts al mismo tiempo o varias veces con un mismo host (saturando además la red).
-Inconsistencias en la tabla de hosts.
-Excepciones producto de inconsistencias en la tabla (ej: se intenta acceder a una fila de la tabla que fue eliminada por otra hebra).
-Entre otras.
Para solucionar estos problemas se ha optado por lo siguiente:
-Solo una hebra puede interrogar a los hosts (la hebra interrogadora). Esta hebra se crea y destruye según se requiera y le pertenece a la GUI. Cuando la hebra refrescadora la necesita, la obtiene desde la GUI.
-Si la hebra interrogadora esta corriendo, no se permite crear una nueva, hasta que acabe la primera.
-Solo un método se ocupa de manejar la tabla (y además es synchronized). También se encarga de avisar de cambios en la lista de hosts a otras hebras.
-Existen una serie de bloques sinchronized que ayudan a mantener la consistencia en la tabla.
-Se utiliza un monitor y los métodos wait() y notify() para pausar o reanudar la hebra interrogadora (cuando ya no se desea refrescamiento automático). Esto permite controlar correctamente el flujo de la hebra y, además, no realizar esperas activas.
-No se utilizan métodos inseguros para el control de las hebras (como stop()). Se implementaron métodos seguros para esto.

La tabla y la lista de hosts

La lista de hosts se implementa como una simple carpeta que contiene todos los hosts conocidos en forma de archivos de objetos serializados. La tabla se refresca leyendo desde este directorio, restituyendo los objetos desde los archivos y pegando los valores de sus atributos en las celdas correspondientes de la tabla.

Objetualización de Hosts

Los hosts son concebidos en su mayor extensión como objetos. Heredan de la clase Host, la cual tiene los atributos que todo host debiese tener, más métodos compartidos entre todos los tipos de hosts. Los tipos son:local o remoto. Cada uno es una clase que contiene métodos y atributos que lo diferencian con Host y con el otro tipo de host.
Esto permite un manejo muy cómodo de los atributos y de las tareas que se pueden realizar por y sobre cada host.