private synchronized void recomputeTerm ( PartitionGroupMembership membership ) { if ( membership == null ) { return ; } // Create a list of candidates based on the availability of members in the group. List < GroupMember > candidates = new ArrayList <> ( ) ; for ( MemberId memberId : membership . members ( ) ) { Member member = clusterMembershipService . getMember ( memberId ) ; if ( member != null && member . isReachable ( ) ) { candidates . add ( new GroupMember ( memberId , MemberGroupId . from ( memberId . id ( ) ) ) ) ; } } // Sort the candidates by a hash of their member ID. candidates . sort ( ( a , b ) -> { int aoffset = Hashing . murmur3_32 ( ) . hashString ( a . memberId ( ) . id ( ) , StandardCharsets . UTF_8 ) . asInt ( ) % partitionId . id ( ) ; int boffset = Hashing . murmur3_32 ( ) . hashString ( b . memberId ( ) . id ( ) , StandardCharsets . UTF_8 ) . asInt ( ) % partitionId . id ( ) ; return aoffset - boffset ; } ) ; // Store the current term in a local variable avoid repeated volatile reads. PrimaryTerm currentTerm = this . currentTerm ; // Compute the primary from the sorted candidates list. GroupMember primary = candidates . isEmpty ( ) ? null : candidates . get ( 0 ) ; // Remove the primary from the candidates list. candidates = candidates . isEmpty ( ) ? Collections . emptyList ( ) : candidates . subList ( 1 , candidates . size ( ) ) ; // If the primary has changed, increment the term. Otherwise, use the current term from the replicated counter. long term = currentTerm != null && Objects . equals ( currentTerm . primary ( ) , primary ) && Objects . equals ( currentTerm . candidates ( ) , candidates ) ? currentTerm ( ) : incrementTerm ( ) ; // Create the new primary term. If the term has changed update the term and trigger an event. PrimaryTerm newTerm = new PrimaryTerm ( term , primary , candidates ) ; if ( ! Objects . equals ( currentTerm , newTerm ) ) { this . currentTerm = newTerm ; LOGGER . debug ( "{} - Recomputed term for partition {}: {}" , clusterMembershipService . getLocalMember ( ) . id ( ) , partitionId , newTerm ) ; post ( new PrimaryElectionEvent ( PrimaryElectionEvent . Type . CHANGED , partitionId , newTerm ) ) ; broadcastCounters ( ) ; } }
Recomputes the current term .