package water; import water.util.Log; /** * A simple message which informs cluster about a new client * which was connected or about existing client who wants to disconnect. * The event is used only in flatfile mode where in case of connecting, it * it allows the client to connect to a single node, which will * inform a cluster about the client. Hence, the rest of nodes will * start ping client with heartbeat, and vice versa. */ public class UDPClientEvent extends UDP { @Override AutoBuffer call(AutoBuffer ab) { // Handle only by non-client nodes if (ab._h2o != H2O.SELF && !H2O.ARGS.client) { ClientEvent ce = new ClientEvent().read(ab); switch(ce.type){ // Connect event is not sent in multicast mode case CONNECT: if(H2O.isFlatfileEnabled()) { H2O.addNodeToFlatfile(ce.clientNode); H2O.reportClient(ce.clientNode); } break; // Regular disconnect event also doesn't have any effect in multicast mode. // However we need to catch the watchdog disconnect event in both multicast and flatfile mode. case DISCONNECT: // handle regular disconnection if(H2O.isFlatfileEnabled()) { Log.info("Client: " + ce.clientNode + " has been disconnected on: " + ab._h2o); H2O.removeNodeFromFlatfile(ce.clientNode); H2O.removeClient(ce.clientNode); } // In case the disconnection comes from the watchdog client, stop the cloud ( in both multicast and flatfile mode ) if(ce.clientNode._heartbeat._watchdog_client){ Log.info("Stopping H2O cloud because watchdog client is disconnecting from the cloud."); // client is sending disconnect message on purpose, we can stop the cloud even without asking // the rest of the nodes for consensus on this H2O.shutdown(0); } break; default: throw new RuntimeException("Unsupported Client event: " + ce.type); } } return ab; } public static class ClientEvent extends Iced<ClientEvent> { public enum Type { CONNECT, DISCONNECT; public void broadcast(H2ONode clientNode) { ClientEvent ce = new ClientEvent(this, clientNode); ce.write(new AutoBuffer(H2O.SELF, udp.client_event._prior).putUdp(udp.client_event)).close(); } } // Type of client event public Type type; // Client public H2ONode clientNode; public ClientEvent() {} public ClientEvent(Type type, H2ONode clientNode) { this.type = type; this.clientNode = clientNode; } } }