@startuml skinparam shadowing false title Tasks and data flow rectangle "relay loop (one per server)" as loop { card "public socket\nrecv_from" as recv card "filter\n(commands, query rate)" as filter } rectangle "server state (Mutex, one per server)" as shared { card "sessions:\nHashMap" as map card "bans\n(bans-.json)" as bans } rectangle "registry (Mutex)" as registry { card "servers by public port,\ntheir key's hash\n(servers.json)" as servers } rectangle "session task (one per client)" as st { card "mpsc Receiver\n(queue: 64)" as rx card "upstream socket\n(connected to ET)" as up } rectangle "heartbeat task (one per server)" as hb { card "interval 5 min" as tick card "probe socket" as probe } rectangle "control API task (axum)" as ctl { card "PUT/GET/DELETE /server" as pairing card "GET /sessions\nGET/PUT/DELETE /bans" as routes } recv --> filter filter --> bans : banned? filter --> map : lookup client map --> rx : try_send(packet)\n(full: drop) rx --> up : send up --> recv : recv, then public.send_to(client) tick --> probe : getinfo tick --> recv : heartbeat via public socket routes --> map : list ports,\ndrop a banned IP's sessions routes --> bans : set / lift routes --> servers : key -> server pairing --> servers : register / leave servers --> loop : start / stop\n(with its heartbeat) @enduml