private void assignNewMaster() { Address oldMasterAddress = node.getMasterAddress(); if (node.joined()) { Collection<Member> members = getMembers(); Member newMaster = null; int size = members.size(); if (size > 1) { Iterator<Member> iterator = members.iterator(); Member member = iterator.next(); if (member.getAddress().equals(oldMasterAddress)) { newMaster = iterator.next(); } else { logger.severe( format( "Old master %s is dead, but the first of member list is a different member %s!", oldMasterAddress, member)); newMaster = member; } } else { logger.warning( format( "Old master %s is dead and this node is not master, " + "but member list contains only %d members: %s", oldMasterAddress, size, members)); } logger.info( format( "Old master %s left the cluster, assigning new master %s", oldMasterAddress, newMaster)); if (newMaster != null) { node.setMasterAddress(newMaster.getAddress()); } else { node.setMasterAddress(null); } } else { node.setMasterAddress(null); } if (logger.isFinestEnabled()) { logger.finest( format("Old master: %s, new master: %s ", oldMasterAddress, node.getMasterAddress())); } if (node.isMaster()) { clusterHeartbeatManager.resetMemberMasterConfirmations(); clusterClock.reset(); } else { clusterHeartbeatManager.sendMasterConfirmation(); } }
public void updateMembers(Collection<MemberInfo> members) { lock.lock(); try { Map<Address, MemberImpl> currentMemberMap = membersMapRef.get(); if (!shouldProcessMemberUpdate(currentMemberMap, members)) { return; } String scopeId = thisAddress.getScopeId(); Collection<MemberImpl> newMembers = new LinkedList<MemberImpl>(); MemberImpl[] updatedMembers = new MemberImpl[members.size()]; int memberIndex = 0; for (MemberInfo memberInfo : members) { MemberImpl member = currentMemberMap.get(memberInfo.getAddress()); if (member == null) { member = createMember(memberInfo, scopeId); newMembers.add(member); long now = Clock.currentTimeMillis(); clusterHeartbeatManager.onHeartbeat(member, now); clusterHeartbeatManager.acceptMasterConfirmation(member, now); Map<Address, MemberImpl> membersRemovedInNotActiveState = new LinkedHashMap<Address, MemberImpl>(membersRemovedInNotActiveStateRef.get()); membersRemovedInNotActiveState.remove(member.getAddress()); membersRemovedInNotActiveStateRef.set( Collections.unmodifiableMap(membersRemovedInNotActiveState)); } updatedMembers[memberIndex++] = member; } setMembers(updatedMembers); sendMembershipEvents(currentMemberMap.values(), newMembers); clusterJoinManager.reset(); clusterHeartbeatManager.heartBeat(); node.setJoined(); logger.info(membersString()); } finally { lock.unlock(); } }
@Override public void reset() { lock.lock(); try { setMembersRef(Collections.singletonMap(thisAddress, thisMember)); clusterHeartbeatManager.reset(); clusterStateManager.reset(); clusterJoinManager.reset(); membersRemovedInNotActiveStateRef.set(Collections.<Address, MemberImpl>emptyMap()); } finally { lock.unlock(); } }
private void removeMember(MemberImpl deadMember) { logger.info("Removing " + deadMember); lock.lock(); try { Map<Address, MemberImpl> members = membersMapRef.get(); final Address deadAddress = deadMember.getAddress(); if (members.containsKey(deadAddress)) { // !!! ORDERED !!! Map<Address, MemberImpl> newMembers = new LinkedHashMap<Address, MemberImpl>(members); newMembers.remove(deadAddress); clusterHeartbeatManager.removeMember(deadMember); setMembersRef(newMembers); if (node.isMaster()) { if (logger.isFinestEnabled()) { logger.finest(deadMember + " is dead, sending remove to all other members..."); } invokeMemberRemoveOperation(deadAddress); } final ClusterState clusterState = clusterStateManager.getState(); if (clusterState == ClusterState.FROZEN || clusterState == ClusterState.PASSIVE) { if (logger.isFinestEnabled()) { logger.finest( deadMember + " is dead, added to members left while cluster is " + clusterState + " state"); } Map<Address, MemberImpl> membersRemovedInNotActiveState = new LinkedHashMap<Address, MemberImpl>(membersRemovedInNotActiveStateRef.get()); membersRemovedInNotActiveState.put(deadAddress, deadMember); membersRemovedInNotActiveStateRef.set( Collections.unmodifiableMap(membersRemovedInNotActiveState)); final InternalPartitionServiceImpl partitionService = node.partitionService; partitionService.cancelReplicaSyncRequestsTo(deadAddress); } else { onMemberRemove(deadMember, newMembers); } // async events sendMembershipEventNotifications( deadMember, unmodifiableSet(new LinkedHashSet<Member>(newMembers.values())), false); } } finally { lock.unlock(); } }
@Override public void init(NodeEngine nodeEngine, Properties properties) { long mergeFirstRunDelayMs = node.groupProperties.getMillis(GroupProperty.MERGE_FIRST_RUN_DELAY_SECONDS); mergeFirstRunDelayMs = (mergeFirstRunDelayMs > 0 ? mergeFirstRunDelayMs : DEFAULT_MERGE_RUN_DELAY_MILLIS); ExecutionService executionService = nodeEngine.getExecutionService(); executionService.register( EXECUTOR_NAME, 2, CLUSTER_EXECUTOR_QUEUE_CAPACITY, ExecutorType.CACHED); long mergeNextRunDelayMs = node.groupProperties.getMillis(GroupProperty.MERGE_NEXT_RUN_DELAY_SECONDS); mergeNextRunDelayMs = (mergeNextRunDelayMs > 0 ? mergeNextRunDelayMs : DEFAULT_MERGE_RUN_DELAY_MILLIS); executionService.scheduleWithFixedDelay( EXECUTOR_NAME, new SplitBrainHandler(node), mergeFirstRunDelayMs, mergeNextRunDelayMs, TimeUnit.MILLISECONDS); clusterHeartbeatManager.init(); }