docs: 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();
      }
    }