Member member = clusterMembershipService.getMember(memberId); if (member != null && member.isReachable()) { candidates.add(new GroupMember(memberId, MemberGroupId.from(memberId.id()))); 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; });
List<Registration> sortRegistrations(List<Registration> registrations) { // Count the number of distinct groups in the registrations list. int groupCount = (int) registrations.stream() .map(r -> r.member().groupId()) .distinct() .count(); Set<MemberGroupId> groups = new HashSet<>(); List<Registration> sortedRegistrations = new LinkedList<>(); // Loop until all registrations have been sorted. while (!registrations.isEmpty()) { // Clear the list of consumed groups. groups.clear(); // For each registration, check if it can be added to the registrations list. Iterator<Registration> iterator = registrations.iterator(); while (iterator.hasNext()) { Registration registration = iterator.next(); // If the registration's group has not been added to the list, add the registration. if (groups.add(registration.member().groupId())) { sortedRegistrations.add(registration); iterator.remove(); // If an instance of a registration from each group has been added, reset the list of registrations. if (groups.size() == groupCount) { groups.clear(); } } } } return sortedRegistrations; }
@Override public CompletableFuture<Void> consume(long index, Consumer<LogRecord> consumer) { return term().thenCompose(term -> { protocol.registerRecordsConsumer(subject, this::handleRecords, threadContext); this.consumer = consumer; this.index = index - 1; return register(term.primary().memberId()); }); } }
@Override public CompletableFuture<Void> start() { registerListeners(); return memberGroupService.start().thenCompose(v -> { MemberGroup group = memberGroupService.getMemberGroup(clusterMembershipService.getLocalMember()); if (group != null) { return primaryElection.enter(new GroupMember(clusterMembershipService.getLocalMember().id(), group.id())); } return CompletableFuture.completedFuture(null); }).thenApply(v -> { started.set(true); return null; }); }
@Override public MemberId primary() { return Futures.get(election.getTerm()) .primary() .memberId(); }
@Override public CompletableFuture<Void> start() { registerListeners(); compactTimer = threadContext.schedule(Duration.ofSeconds(30), this::compact); return memberGroupService.start().thenComposeAsync(v -> { MemberGroup group = memberGroupService.getMemberGroup(clusterMembershipService.getLocalMember()); primaryElection.addListener(primaryElectionListener); if (group != null) { return primaryElection.enter(new GroupMember(clusterMembershipService.getLocalMember().id(), group.id())) .thenApply(term -> { changeRole(term); return null; }); } return CompletableFuture.completedFuture(null); }, threadContext).thenApply(v -> { started.set(true); return null; }); }
@Override public MemberId primary() { return Futures.get(election.getTerm()) .primary() .memberId(); }
@Override public CompletableFuture<Void> start() { registerListeners(); compactTimer = threadContext.schedule(Duration.ofSeconds(30), this::compact); return memberGroupService.start().thenComposeAsync(v -> { MemberGroup group = memberGroupService.getMemberGroup(clusterMembershipService.getLocalMember()); primaryElection.addListener(primaryElectionListener); if (group != null) { return primaryElection.enter(new GroupMember(clusterMembershipService.getLocalMember().id(), group.id())) .thenApply(term -> { changeRole(term); return null; }); } return CompletableFuture.completedFuture(null); }, threadContext).thenApply(v -> { started.set(true); return null; }); }
@Override public CompletableFuture<Long> append(byte[] value) { CompletableFuture<Long> future = new CompletableFuture<>(); term().thenCompose(term -> protocol.append(term.primary().memberId(), AppendRequest.request(value))) .whenCompleteAsync((response, error) -> { if (error == null) { if (response.status() == LogResponse.Status.OK) { future.complete(response.index()); } else { future.completeExceptionally(new PrimitiveException.Unavailable()); } } else { future.completeExceptionally(error); } }, threadContext); return future; } }
/** * Returns the current server role. * * @return the current server role */ public Role getRole() { return Objects.equals(Futures.get(primaryElection.getTerm()).primary().memberId(), clusterMembershipService.getLocalMember().id()) ? Role.PRIMARY : Role.BACKUP; }
/** * Handles a cluster event. */ private void handleClusterEvent(ClusterMembershipEvent event) { PrimaryTerm term = this.term; if (term != null && event.type() == ClusterMembershipEvent.Type.MEMBER_REMOVED && event.subject().id().equals(term.primary().memberId())) { threadContext.execute(() -> { state = PrimitiveState.SUSPENDED; stateChangeListeners.forEach(l -> l.accept(state)); }); } }
/** * Returns the current server role. * * @return the current server role */ public DistributedLogServer.Role getRole() { return Objects.equals(Futures.get(primaryElection.getTerm()).primary().memberId(), clusterMembershipService.getLocalMember().id()) ? DistributedLogServer.Role.LEADER : DistributedLogServer.Role.FOLLOWER; }
/** * Handles a replica change event. */ private void changeReplicas(PrimaryTerm term) { threadContext.execute(() -> { if (this.term == null || term.term() > this.term.term()) { this.term = term; consumer.register(term.primary().memberId()); } }); }
@Override public CompletableFuture<Void> close() { CompletableFuture<Void> future = new CompletableFuture<>(); PrimaryTerm term = this.term; if (term.primary() != null) { protocol.close(term.primary().memberId(), new CloseRequest(descriptor, sessionId.id())) .whenCompleteAsync((response, error) -> { try { protocol.unregisterEventListener(sessionId); clusterMembershipService.removeListener(membershipEventListener); primaryElection.removeListener(primaryElectionListener); } finally { future.complete(null); } }, threadContext); } else { future.complete(null); } return future; }
/** * Handles a cluster event. */ private void handleClusterEvent(ClusterMembershipEvent event) { PrimaryTerm term = this.term; if (term != null && event.type() == ClusterMembershipEvent.Type.MEMBER_REMOVED && event.subject().id().equals(term.primary().memberId())) { changeState(PrimitiveState.SUSPENDED); } }
log.debug("{} - Term changed: {}", memberId, term); currentTerm = term.term(); leader = term.primary() != null ? term.primary().memberId() : null; followers = term.backups(replicationFactor - 1) .stream()
log.debug("Term changed: {}", term); currentTerm = term.term(); primary = term.primary() != null ? term.primary().memberId() : null; backups = term.backups(descriptor.backups()) .stream()
PrimaryTerm term = this.term; if (term.primary() != null) { protocol.execute(term.primary().memberId(), request).whenCompleteAsync((response, error) -> { if (error == null) { log.trace("Received {}", response);
@Override public CompletableFuture<Void> consume(long index, Consumer<LogRecord> consumer) { return term().thenCompose(term -> { protocol.registerRecordsConsumer(subject, this::handleRecords, threadContext); this.consumer = consumer; this.index = index - 1; return register(term.primary().memberId()); }); } }
@Override public MemberId primary() { return Futures.get(election.getTerm()) .primary() .memberId(); }