@Override protected void doClose() throws ElasticsearchException { masterFD.close(); nodesFD.close(); publishClusterState.close(); membership.close(); pingService.close(); }
@Override protected void doStop() throws ElasticsearchException { pingService.stop(); masterFD.stop("zen disco stop"); nodesFD.stop(); initialStateSent.set(false); if (sendLeaveRequest) { if (!master && latestDiscoNodes.masterNode() != null) { try { membership.sendLeaveRequestBlocking( latestDiscoNodes.masterNode(), localNode, TimeValue.timeValueSeconds(1)); } catch (Exception e) { logger.debug( "failed to send leave request to master [{}]", e, latestDiscoNodes.masterNode()); } } else { DiscoveryNode[] possibleMasters = electMaster.nextPossibleMasters(latestDiscoNodes.nodes().values(), 5); for (DiscoveryNode possibleMaster : possibleMasters) { if (localNode.equals(possibleMaster)) { continue; } try { membership.sendLeaveRequest(latestDiscoNodes.masterNode(), possibleMaster); } catch (Exception e) { logger.debug( "failed to send leave request from master [{}] to possible master [{}]", e, latestDiscoNodes.masterNode(), possibleMaster); } } } } master = false; if (currentJoinThread != null) { try { currentJoinThread.interrupt(); } catch (Exception e) { // ignore } } }
@Override protected void doStart() throws ElasticsearchException { Map<String, String> nodeAttributes = discoveryNodeService.buildAttributes(); // note, we rely on the fact that its a new id each time we start, see FD and "kill -9" handling final String nodeId = getNodeUUID(settings); localNode = new DiscoveryNode( settings.get("name"), nodeId, transportService.boundAddress().publishAddress(), nodeAttributes, version); latestDiscoNodes = new DiscoveryNodes.Builder().put(localNode).localNodeId(localNode.id()).build(); nodesFD.updateNodes(latestDiscoNodes); pingService.start(); // do the join on a different thread, the DiscoveryService waits for 30s anyhow till it is // discovered asyncJoinCluster(); }
private DiscoveryNode findMaster() { ZenPing.PingResponse[] fullPingResponses = pingService.pingAndWait(pingTimeout); if (fullPingResponses == null) { logger.trace("No full ping responses"); return null; } if (logger.isTraceEnabled()) { StringBuilder sb = new StringBuilder("full ping responses:"); if (fullPingResponses.length == 0) { sb.append(" {none}"); } else { for (ZenPing.PingResponse pingResponse : fullPingResponses) { sb.append("\n\t--> ") .append("target [") .append(pingResponse.target()) .append("], master [") .append(pingResponse.master()) .append("]"); } } logger.trace(sb.toString()); } // filter responses List<ZenPing.PingResponse> pingResponses = Lists.newArrayList(); for (ZenPing.PingResponse pingResponse : fullPingResponses) { DiscoveryNode node = pingResponse.target(); if (masterElectionFilterClientNodes && (node.clientNode() || (!node.masterNode() && !node.dataNode()))) { // filter out the client node, which is a client node, or also one that is not data and not // master (effectively, client) } else if (masterElectionFilterDataNodes && (!node.masterNode() && node.dataNode())) { // filter out data node that is not also master } else { pingResponses.add(pingResponse); } } if (logger.isDebugEnabled()) { StringBuilder sb = new StringBuilder("filtered ping responses: (filter_client[") .append(masterElectionFilterClientNodes) .append("], filter_data[") .append(masterElectionFilterDataNodes) .append("])"); if (pingResponses.isEmpty()) { sb.append(" {none}"); } else { for (ZenPing.PingResponse pingResponse : pingResponses) { sb.append("\n\t--> ") .append("target [") .append(pingResponse.target()) .append("], master [") .append(pingResponse.master()) .append("]"); } } logger.debug(sb.toString()); } List<DiscoveryNode> pingMasters = newArrayList(); for (ZenPing.PingResponse pingResponse : pingResponses) { if (pingResponse.master() != null) { pingMasters.add(pingResponse.master()); } } Set<DiscoveryNode> possibleMasterNodes = Sets.newHashSet(); possibleMasterNodes.add(localNode); for (ZenPing.PingResponse pingResponse : pingResponses) { possibleMasterNodes.add(pingResponse.target()); } // if we don't have enough master nodes, we bail, even if we get a response that indicates // there is a master by other node, we don't see enough... if (!electMaster.hasEnoughMasterNodes(possibleMasterNodes)) { return null; } if (pingMasters.isEmpty()) { // lets tie break between discovered nodes DiscoveryNode electedMaster = electMaster.electMaster(possibleMasterNodes); if (localNode.equals(electedMaster)) { return localNode; } } else { DiscoveryNode electedMaster = electMaster.electMaster(pingMasters); if (electedMaster != null) { return electedMaster; } } return null; }