@Override public void onClose(Session session) { onSessionEnd(session); } }
GroupMember primary() { if (primary == null) { return null; } else { return primary.member(); } }
@Override public String id() { return name(); }
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(); } }); }
/** * Applies an {@link PrimaryElectorOperations.GetTerm} commit. * * @param commit GetLeadership commit * @return leader */ protected PrimaryTerm getTerm(Commit<? extends PrimaryElectorOperations.GetTerm> commit) { PartitionId partitionId = commit.value().partitionId(); try { return term(partitionId); } catch (Exception e) { getLogger().error("State machine operation failed", e); throw Throwables.propagate(e); } }
@Override public PrimaryElection getElectionFor(PartitionId partitionId) { return elections.computeIfAbsent(partitionId, id -> { HashBasedPrimaryElection election = new HashBasedPrimaryElection(partitionId, clusterMembershipService, groupMembershipService, messagingService, executor); election.addListener(primaryElectionListener); return election; }); }
PrimaryTerm term() { return new PrimaryTerm(term, primary(), candidates()); }
private void updateCounters(Map<MemberId, Integer> counters) { for (Map.Entry<MemberId, Integer> entry : counters.entrySet()) { this.counters.compute(entry.getKey(), (key, value) -> { if (value == null || value < entry.getValue()) { return entry.getValue(); } return value; }); } updateTerm(currentTerm()); }
private PartitionGroupInfo handleBootstrap(PartitionGroupInfo info) { try { updatePartitionGroups(info); } catch (Exception e) { // Log the exception LOGGER.warn("{}", e.getMessage()); } return new PartitionGroupInfo(membershipService.getLocalMember().id(), systemGroup, Lists.newArrayList(groups.values())); }
/** * Bootstraps the service. */ private CompletableFuture<Void> bootstrap() { return bootstrap(0, new CompletableFuture<>()); }
@Override public PrimitiveService newService(ServiceConfig confi) { return new PrimaryElectorService(); }
public PrimaryElectorService() { super(PrimaryElectorType.instance()); }
@Override @SuppressWarnings("unchecked") public PrimaryElection getElectionFor(PartitionId partitionId) { return elections.computeIfAbsent(partitionId, id -> new DefaultPrimaryElection(partitionId, proxy, this)); }
private PrimaryTerm term(PartitionId partitionId) { ElectionState electionState = elections.get(partitionId); return electionState != null ? electionState.term() : null; }
@Override public String toString() { return toStringHelper(this) .add("name", name()) .toString(); } }
/** * Schedules rebalancing of primaries. */ private void scheduleRebalance() { if (rebalanceTimer != null) { rebalanceTimer.cancel(); } rebalanceTimer = getScheduler().schedule(REBALANCE_DURATION, this::rebalance); }
/** * Handles a cluster membership event. */ private void handleClusterMembershipEvent(ClusterMembershipEvent event) { if (event.type() == ClusterMembershipEvent.Type.MEMBER_ADDED || event.type() == ClusterMembershipEvent.Type.MEMBER_REMOVED) { recomputeTerm(groupMembershipService.getMembership(partitionId.group())); } }
@Override public void onExpire(Session session) { onSessionEnd(session); }
/** * Bootstraps the service from the given node. */ @SuppressWarnings("unchecked") private CompletableFuture<Void> bootstrap(Member member) { return bootstrap(member, new CompletableFuture<>()); }