El socket abierto
Un socket abierto no es un equipo conectado. Un comando enviado no es un comando que llegó. Y una confirmación no es una acción ejecutada.
Simula un día de una flota con conexiones TCP persistentes. Cada equipo manda posiciones cuando se mueve y latidos cuando está parado; de vez en cuando pierde la cobertura, y si pasa más tiempo sin tráfico del que aguanta el NAT del operador, la conexión muere sin que nadie avise. El servidor se entera tarde, según el mecanismo que tenga. En ese día se mandan comandos, y cada uno se sigue por sus estados. Aparte, simula el reinicio del gateway y cuánto tarda toda la flota en volver a tener sesión. Todo es modelo, con supuestos que se pueden mover; nada es medición. Corre en tu navegador y no envía nada.
CUÁNTO TARDA EN ENTERARSE
Cuánto tarda el servidor en enterarse de que una conexión murió, desde que murió de verdad. La barra llega a la mediana; la raya marca el p95.
Los comandos
Cuatro estados que no son lo mismo: generado, enviado a la conexión, confirmado por el equipo, ejecutado y verificado. Un comando escrito en un socket muerto queda en «enviado» para siempre si nadie espera la confirmación.
Dos sesiones del mismo equipo
Registro por generación: la sesión nueva y autenticada sustituye a la vieja y la cierra; el cierre tardío de la vieja no toca a la nueva. Registro por socket: cada mensaje registra el socket del equipo y, cuando cualquier sesión del equipo se cierra, borra la entrada; el equipo vuelve a aparecer con su siguiente mensaje.
El reinicio del gateway
SESIONES LISTAS PARA COMANDOS
Qué parte de la flota tiene su sesión lista para recibir comandos, segundo a segundo desde que cae el gateway.
Cómo calcula
Cada equipo hace de dos a cuatro viajes al día, entre las 6:00 y las 20:00, de 20 a 90 minutos; en movimiento manda una posición cada tantos segundos y parado, un latido. Pierde la cobertura las veces de arriba, en momentos al azar, por un tiempo entre un minuto y el máximo. Una conexión muere de verdad cuando el servidor ya no puede alcanzar al equipo: al perder la cobertura, o cuando pasa más tiempo sin tráfico del que aguanta el NAT; en ese caso, el equipo se entera al mandar su siguiente mensaje y reconecta. El servidor no recibe aviso de ninguna de las dos.
El servidor se entera por actividad de la aplicación (desde el último mensaje, los latidos que deben faltar por el intervalo del latido), por el keepalive de TCP (la inactividad más las sondas) o, con registro por generación, al llegar la sesión nueva del mismo equipo. Un comando busca la sesión en el registro; si la sesión vive, llega y se confirma; si está muerta, se escribe y no llega, y tras la espera se reenvía por lo que diga el registro en ese momento, hasta vencer. Un latido cuesta tres paquetes con su cabecera de 40 bytes (el latido, la respuesta y un ACK) más su contenido; una reconexión, el saludo de TCP, el login, su respuesta y un ACK.
En el reinicio, el gateway cae y sus equipos reconectan: con intervalo fijo, todos a la vez cada tantos segundos; con espera al azar, cada uno después de un tiempo al azar y, si falla, con una espera que crece. Mientras el gateway está caído, el sistema operativo contesta que no hay nadie y el equipo lo sabe al instante. Ya arriba, cada segundo el gateway mete a su cola lo que cabe; con la cola llena, Linux descarta el SYN sin contestar y el equipo lo reenvía a 1, 3 y 7 segundos. El gateway acepta, autentica e inicializa a su ritmo; si el equipo espera su login más de lo que aguanta, abandona el intento y vuelve a su política de reintento. Una sesión está lista cuando ya puede recibir comandos. Con varias instancias, las conexiones se reparten entre las que están arriba. El azar lleva semilla, y el día de inicio es uno intermedio entre cincuenta.
Lo que no modela: que una pérdida corta de cobertura sin cambio de IP no siempre tumba la conexión (aquí toda pérdida la corta, el peor caso); los NAT que descartan en silencio en vez de contestar, con lo que el equipo tarda más en enterarse; que el keepalive de TCP viene apagado por omisión en cada socket; el error de escritura que TCP da tras unos quince minutos de reintentos (en Linux), que también avisaría de una conexión muerta; que el servidor también mande tráfico y con eso mantenga vivo el NAT; equipos que tardan en darse cuenta de que perdieron la cobertura; cómo cobra cada operador los datos; varios procesos por instancia, y que un comando confirmado no se ejecute por algo del vehículo. Los tiempos del NAT, las pérdidas de cobertura y las capacidades del gateway son supuestos, no mediciones de un operador ni de nuestros gateways.