Estoy usando una base de datos de postgres para mantener una lista de salas y usuarios conectados a cada sala.
Los usuarios pueden ingresar a una sala cuando lo deseen, pero deben abandonar la sala cuando cierran el navegador.
Un buen flujo de eventos debe ser
El usuario ingresa a la habitación (la var de la habitación del usuario está configurada) -> ... -> El usuario se desconecta y el servidor notifica (la var de la habitación del usuario no está configurada)
Pero, ¿y si esto sucede?
El usuario ingresa a la habitación (la var de la habitación del usuario está configurada) -> ... -> El servidor falla o se apaga para recibir actualizaciones -> El usuario se desconecta y el servidor no se da cuenta (la var de la habitación del usuario aún está configurada) -> El servidor está nuevamente encendido
En este último caso, el estado de la base de datos ya está roto. ¿Cuál es la mejor manera de lidiar con algo así? Gracias
Dividamos la respuesta en 2 aspectos:
Aspecto del usuario:
Independientemente del idioma en cuestión, debe estar al tanto de los eventos de desconexión mediante un manejo de eventos/excepciones de Socket.
Si el servidor falla, su usuario experimentará una desconexión abrupta del socket/cierre de la conexión/terminación de la sesión, según el marco que esté utilizando. Los sockets TCP también tienen keepalive ( SO_KEEPALIVE ) exactamente para eso (por lo general, puede controlar estas configuraciones (o similares) desde el protocolo de alto nivel.
Entonces, todo lo que necesita hacer en ese caso es ejecutar el código de mantenimiento en el extremo del usuario (desestablecer una variable en su caso descrito)
Aspecto del servidor:
Es un poco más complicado aquí. Básicamente, lo que está buscando es la administración de estado efímero, es decir, la capacidad de reaccionar ante la terminación abrupta del servicio/servidor (caídas del servidor que dan como resultado un estado corrupto/sucio) y la limpieza posterior.
Para eso existen Tecnologías como Zookeeper o Consul. Personalmente, recomiendo Zookeeper, ya que he creado soluciones similares en el pasado varias veces.
Con zookeeper, cuando su servidor se inicia, puede, por ejemplo, crear un nodo EPHEMERAL . Ese nodo se creará una vez que el servidor se active y permanecerá allí mientras el servidor esté activo y conectado al clúster de Zookeeper. Si el servidor falla inesperadamente, este nodo se elimina.
Luego puede tener una aplicación/secuencia de comandos separada que escuche los eventos en ese nodo/ruta zk. Si se elimina repentinamente, puede ejecutar una rutina de limpieza en la base de datos.
Este enfoque admite múltiples instancias de aplicaciones, por supuesto: puede escuchar eventos en una ruta y hacer que todas las instancias del servidor se registren usando diferentes nodos debajo de él. El nodo eliminado puede contener identificadores específicos de la instancia y puede usarlos para limpiar el estado de la instancia específica de la base de datos.
También puede ser una buena elección eliminar la tarea de limpieza/mantenimiento a un componente separado.
(Tenga en cuenta que ZooKeeper requiere una cuidadosa atención cuando se trata de eventos de conexión/estado)
Algún material de lectura adicional de Zookeeper
Pensamientos finales:
Por supuesto, la respuesta se puede ajustar en función de las necesidades específicas que no se presentaron en la pregunta.
Cuando construyo una solución compleja y con estado, mi objetivo personal es lidiar con fallas en todos los extremos de las soluciones, jugando "seguro" siempre que sea posible.