private boolean prepareClusterState(ClusterServiceImpl clusterService) { if (!preCheckClusterState(clusterService)) { return false; } long until = Clock.currentTimeMillis() + mergeNextRunDelayMs; while (clusterService.getClusterState() == ClusterState.ACTIVE) { try { clusterService.changeClusterState(ClusterState.FROZEN); return true; } catch (Exception e) { String error = e.getClass().getName() + ": " + e.getMessage(); logger.warning("While freezing cluster state! " + error); } if (Clock.currentTimeMillis() >= until) { logger.warning( "Could not change cluster state to FROZEN in time. " + "Postponing merge process until next attempt."); return false; } try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { logger.warning("Interrupted while preparing cluster for merge!"); // restore interrupt flag Thread.currentThread().interrupt(); return false; } } return false; }
@Override public void run() { final ClusterServiceImpl clusterService = getService(); final ILogger logger = getLogger(); final ClusterState clusterState = clusterService.getClusterState(); if (clusterState == ClusterState.PASSIVE) { final NodeEngineImpl nodeEngine = (NodeEngineImpl) getNodeEngine(); if (nodeEngine.isRunning()) { logger.info( "Shutting down node in cluster passive state. Requested by: " + getCallerAddress()); new Thread( new Runnable() { @Override public void run() { final Node node = nodeEngine.getNode(); node.hazelcastInstance.getLifecycleService().shutdown(); } }, nodeEngine.getHazelcastThreadGroup().getThreadNamePrefix(".clusterShutdown")) .start(); } else { logger.info("Node is already shutting down. NodeState: " + nodeEngine.getNode().getState()); } } else { logger.severe( "Can not shut down node because cluster is in " + clusterState + " state. Requested by: " + getCallerAddress()); } }
@SuppressWarnings({ "checkstyle:methodlength", "checkstyle:returncount", "checkstyle:npathcomplexity", "checkstyle:cyclomaticcomplexity" }) protected boolean shouldMerge(JoinMessage joinMessage) { if (joinMessage == null) { return false; } try { boolean validJoinRequest = clusterJoinManager.validateJoinMessage(joinMessage); if (!validJoinRequest) { logger.finest( "Cannot process split brain merge message from " + joinMessage.getAddress() + ", since join-message could not be validated."); return false; } } catch (Exception e) { logger.finest(e.getMessage()); return false; } try { if (clusterService.getMember(joinMessage.getAddress()) != null) { if (logger.isFinestEnabled()) { logger.finest( "Should not merge to " + joinMessage.getAddress() + ", because it is already member of this cluster."); } return false; } final ClusterState clusterState = clusterService.getClusterState(); if (clusterState != ClusterState.ACTIVE) { if (logger.isFinestEnabled()) { logger.finest( "Should not merge to " + joinMessage.getAddress() + ", because this cluster is in " + clusterState + " state."); } return false; } Collection<Address> targetMemberAddresses = joinMessage.getMemberAddresses(); if (targetMemberAddresses.contains(node.getThisAddress())) { node.nodeEngine .getOperationService() .send(new MemberRemoveOperation(node.getThisAddress()), joinMessage.getAddress()); logger.info( node.getThisAddress() + " CANNOT merge to " + joinMessage.getAddress() + ", because it thinks this-node as its member."); return false; } Collection<Address> thisMemberAddresses = clusterService.getMemberAddresses(); for (Address address : thisMemberAddresses) { if (targetMemberAddresses.contains(address)) { logger.info( node.getThisAddress() + " CANNOT merge to " + joinMessage.getAddress() + ", because it thinks " + address + " as its member. " + "But " + address + " is member of this cluster."); return false; } } int targetDataMemberCount = joinMessage.getDataMemberCount(); int currentDataMemberCount = clusterService.getSize(DATA_MEMBER_SELECTOR); if (targetDataMemberCount > currentDataMemberCount) { // I should join the other cluster logger.info( node.getThisAddress() + " is merging to " + joinMessage.getAddress() + ", because : joinMessage.getDataMemberCount() > currentDataMemberCount [" + (targetDataMemberCount + " > " + currentDataMemberCount) + ']'); if (logger.isFinestEnabled()) { logger.finest(joinMessage.toString()); } return true; } else if (targetDataMemberCount == currentDataMemberCount) { // compare the hashes if (node.getThisAddress().hashCode() > joinMessage.getAddress().hashCode()) { logger.info( node.getThisAddress() + " is merging to " + joinMessage.getAddress() + ", because : node.getThisAddress().hashCode() > joinMessage.address.hashCode() " + ", this node member count: " + currentDataMemberCount); if (logger.isFinestEnabled()) { logger.finest(joinMessage.toString()); } return true; } else { logger.info( joinMessage.getAddress() + " should merge to this node " + ", because : node.getThisAddress().hashCode() < joinMessage.address.hashCode() " + ", this node data member count: " + currentDataMemberCount); } } else { logger.info( joinMessage.getAddress() + " should merge to this node " + ", because : currentDataMemberCount > joinMessage.getDataMemberCount() [" + (currentDataMemberCount + " > " + targetDataMemberCount) + ']'); } } catch (Throwable e) { logger.severe(e); } return false; }