int registrationCount = countPrimaries(registration); for (int i = 0; i < registrations.size(); i++) { if (countPrimaries(registrations.get(i)) > registrationCount) { updatedRegistrations.add(i, registration); added = true; List<Registration> sortedRegistrations = sortRegistrations(updatedRegistrations); termStartTime = System.currentTimeMillis(); return new ElectionState( partitionId, sortedRegistrations,
private void onSessionEnd(Session session) { listeners.remove(session.sessionId().id()); Set<PartitionId> partitions = elections.keySet(); partitions.forEach(partitionId -> { PrimaryTerm oldTerm = term(partitionId); elections.compute(partitionId, (k, v) -> v.cleanup(session)); PrimaryTerm newTerm = term(partitionId); if (!Objects.equals(oldTerm, newTerm)) { notifyTermChange(partitionId, newTerm); scheduleRebalance(); } }); }
int countPrimaries(Registration registration) { if (registration == null) { return 0; } return (int) elections.entrySet().stream() .filter(entry -> !entry.getKey().equals(partitionId)) .filter(entry -> entry.getValue().primary != null) .filter(entry -> { // Get the topic leader's identifier and a list of session identifiers. // Then return true if the leader's identifier matches any of the session's candidates. GroupMember leaderId = entry.getValue().primary(); List<GroupMember> sessionCandidates = entry.getValue().registrations.stream() .filter(r -> r.sessionId == registration.sessionId) .map(r -> r.member()) .collect(Collectors.toList()); return sessionCandidates.stream() .anyMatch(candidate -> Objects.equals(candidate, leaderId)); }) .count(); }
if (primary.sessionId() == session.sessionId().id()) { if (!updatedRegistrations.isEmpty()) { return new ElectionState( partitionId, updatedRegistrations, elections); } else { return new ElectionState( partitionId, updatedRegistrations, return new ElectionState( partitionId, updatedRegistrations,
PrimaryTerm newTerm = elections.compute(partitionId, (k, v) -> { if (v == null) { return new ElectionState(partitionId, registration, elections); } else { if (!v.isDuplicate(registration)) { return new ElectionState(v).addRegistration(registration); } else { return v; .term();
for (ElectionState election : elections.values()) { int primaryCount = election.countPrimaries(election.primary); for (Registration candidate : election.registrations) { if (minCandidateCount == 0) { minCandidateCount = election.countPrimaries(candidate); } else { minCandidateCount = Math.min(minCandidateCount, election.countPrimaries(candidate)); if (election.countPrimaries(candidate) < primaryCount) { PrimaryTerm oldTerm = election.term(); elections.put(election.partitionId, election.transfer(candidate.member())); PrimaryTerm newTerm = term(election.partitionId); if (!Objects.equals(oldTerm, newTerm)) {
ElectionState transfer(GroupMember member) { Registration newLeader = registrations.stream() .filter(r -> Objects.equals(r.member(), member)) .findFirst() .orElse(null); if (newLeader != null) { return new ElectionState( partitionId, registrations, newLeader, term + 1, System.currentTimeMillis(), elections); } else { return this; } } }
PrimaryTerm term() { return new PrimaryTerm(term, primary(), candidates()); }
private PrimaryTerm term(PartitionId partitionId) { ElectionState electionState = elections.get(partitionId); return electionState != null ? electionState.term() : null; }