use of com.netflix.titus.api.clustermembership.model.ClusterMember in project titus-control-plane by Netflix.
the class KubeRegistrationActions method registerLocal.
public static Mono<Function<KubeClusterState, KubeClusterState>> registerLocal(KubeContext context, KubeClusterState kubeClusterState, Function<ClusterMember, ClusterMembershipRevision<ClusterMember>> selfUpdate) {
ClusterMember localMember = kubeClusterState.getLocalMemberRevision().getCurrent();
ClusterMembershipRevision<ClusterMember> newRevision = setRegistrationStatus(selfUpdate.apply(localMember), true);
KubeMembershipExecutor membershipExecutor = context.getKubeMembershipExecutor();
Mono<ClusterMembershipRevision<ClusterMember>> monoAction;
if (kubeClusterState.isRegistered()) {
monoAction = membershipExecutor.updateLocal(newRevision).onErrorResume(e -> {
if (!KubeUtils.is4xx(e)) {
return Mono.error(e);
}
int status = KubeUtils.getHttpStatusCode(e);
if (status == 404) {
return membershipExecutor.createLocal(newRevision);
}
// Bad or stale data record. Remove it first and than register.
return membershipExecutor.removeMember(newRevision.getCurrent().getMemberId()).then(membershipExecutor.createLocal(newRevision));
});
} else {
monoAction = membershipExecutor.createLocal(newRevision).onErrorResume(e -> {
if (!KubeUtils.is4xx(e)) {
return Mono.error(e);
}
// Bad or stale data record. Remove it first and than register.
return membershipExecutor.removeMember(newRevision.getCurrent().getMemberId()).then(membershipExecutor.createLocal(newRevision));
});
}
return monoAction.onErrorMap(KubeUtils::toConnectorException).map(update -> currentState -> currentState.setMustRegister(true).setLocalClusterMemberRevision(update, true));
}
use of com.netflix.titus.api.clustermembership.model.ClusterMember in project titus-control-plane by Netflix.
the class KubeRegistrationActions method unregisterLocal.
public static Mono<Function<KubeClusterState, KubeClusterState>> unregisterLocal(KubeContext context, KubeClusterState kubeClusterState, Function<ClusterMember, ClusterMembershipRevision<ClusterMember>> selfUpdate) {
if (!kubeClusterState.isRegistered()) {
return Mono.just(Function.identity());
}
ClusterMember localMember = kubeClusterState.getLocalMemberRevision().getCurrent();
ClusterMembershipRevision<ClusterMember> newRevision = setRegistrationStatus(selfUpdate.apply(localMember), false);
Mono monoAction = context.getKubeMembershipExecutor().removeMember(kubeClusterState.getLocalMemberRevision().getCurrent().getMemberId());
return ((Mono<Function<KubeClusterState, KubeClusterState>>) monoAction).onErrorMap(KubeUtils::toConnectorException).thenReturn(currentState -> currentState.setMustRegister(false).setLocalClusterMemberRevision(newRevision, false));
}
use of com.netflix.titus.api.clustermembership.model.ClusterMember in project titus-control-plane by Netflix.
the class SingleClusterMemberResolver method checkSnapshot.
private Optional<String> checkSnapshot(ClusterMembershipEvent.Snapshot snapshot) {
if (CollectionsExt.isNullOrEmpty(snapshot.getRevisionsList())) {
return Optional.of(String.format("[%s] Empty cluster membership list", name));
}
ClusterMember member = toCoreClusterMember(snapshot.getRevisionsList().get(0).getCurrent());
ClusterMemberVerifierResult result = clusterMemberVerifier.verify(member);
return result.isValid() ? Optional.empty() : Optional.of(result.getMessage());
}
use of com.netflix.titus.api.clustermembership.model.ClusterMember in project titus-control-plane by Netflix.
the class MultiNodeClusterMemberResolver method refresh.
private void refresh() {
// Always first add missing seed nodes.
addNewSeeds();
ClusterMembershipSnapshot resolvedSnapshot = buildSnapshot();
// If no members, we cannot make any progress, so exit.
if (resolvedSnapshot.getMemberRevisions().isEmpty()) {
Set<String> toRemove = memberResolversByIpAddress.keySet().stream().filter(ip -> !isSeedIp(ip)).collect(Collectors.toSet());
disconnectTerminatedMembers(toRemove);
logger.debug("Cannot connect to any cluster member. Known members: {}", toResolvedMembersString());
return;
}
// As IP address can be reused take always more recent record first.
Map<String, ClusterMembershipRevision<ClusterMember>> resolvedMembersByIp = new HashMap<>();
resolvedSnapshot.getMemberRevisions().forEach((memberId, revision) -> {
String ipAddress = addressSelector.apply(revision.getCurrent()).getIpAddress();
ClusterMembershipRevision<ClusterMember> previous = resolvedMembersByIp.get(ipAddress);
if (previous == null || previous.getTimestamp() < revision.getTimestamp()) {
resolvedMembersByIp.put(ipAddress, revision);
}
});
// Find terminated members.
Set<String> toRemove = memberResolversByIpAddress.keySet().stream().filter(ip -> !resolvedMembersByIp.containsKey(ip) && !isSeedIp(ip)).collect(Collectors.toSet());
disconnectTerminatedMembers(toRemove);
// Find new members that we should connect to.
Set<String> toAdd = resolvedMembersByIp.keySet().stream().filter(ip -> !memberResolversByIpAddress.containsKey(ip)).collect(Collectors.toSet());
connectNewMembers(resolvedMembersByIp, toAdd);
}
use of com.netflix.titus.api.clustermembership.model.ClusterMember in project titus-control-plane by Netflix.
the class GrpcClusterMembershipLeaderNameResolver method refresh.
private void refresh(ClusterMembershipSnapshot snapshot) {
try {
Optional<ClusterMembershipRevision<ClusterMember>> leaderOpt = snapshot.getLeaderRevision().flatMap(l -> Optional.ofNullable(snapshot.getMemberRevisions().get(l.getCurrent().getMemberId())));
if (leaderOpt.isPresent()) {
ClusterMembershipRevision<ClusterMember> memberRevision = leaderOpt.get();
ClusterMemberAddress address = addressSelector.apply(memberRevision.getCurrent());
if (lastLeader == null || !lastLeader.getCurrent().getMemberId().equals(memberRevision.getCurrent().getMemberId())) {
logger.info("New leader: {}", memberRevision);
Evaluators.acceptNotNull(leaderMetrics, LeaderMetrics::close);
lastLeader = memberRevision;
leaderMetrics = new LeaderMetrics(lastLeader, titusRuntime);
} else {
logger.debug("Refreshing: {}", lastLeader);
}
EquivalentAddressGroup server = new EquivalentAddressGroup(new InetSocketAddress(address.getIpAddress(), address.getPortNumber()));
List<EquivalentAddressGroup> servers = Collections.singletonList(server);
listener.onAddresses(servers, Attributes.EMPTY);
} else {
if (lastLeader != null) {
leaderMetrics.close();
lastLeader = null;
leaderMetrics = null;
logger.warn("No leader");
}
listener.onError(Status.UNAVAILABLE.withDescription("Unable to resolve leader server"));
}
} catch (Exception e) {
logger.error("Unable to create server with error: ", e);
listener.onError(Status.UNAVAILABLE.withCause(e));
}
}
Aggregations