Search in sources :

Example 6 with ClusterMember

use of com.netflix.titus.api.clustermembership.model.ClusterMember in project titus-control-plane by Netflix.

the class DefaultClusterMembershipService method clusterStateEvaluator.

private Mono<Void> clusterStateEvaluator(ExecutionContext context) {
    return Mono.defer(() -> {
        ClusterMember localMember = connector.getLocalClusterMemberRevision().getCurrent();
        ClusterMemberLeadershipState localLeadershipState = connector.getLocalLeadershipRevision().getCurrent().getLeadershipState();
        HealthStatus health = healthIndicator.health();
        // Explicitly disabled
        if (!configuration.isLeaderElectionEnabled() || !localMember.isEnabled()) {
            if (localLeadershipState == ClusterMemberLeadershipState.NonLeader) {
                logger.info("Local member excluded from the leader election. Leaving the leader election process");
                return connector.leaveLeadershipGroup(true).flatMap(success -> success ? connector.register(current -> toInactive(current, "Marked by a user as disabled")).ignoreElement().cast(Void.class) : Mono.empty());
            }
            if (localLeadershipState == ClusterMemberLeadershipState.Disabled && localMember.isActive()) {
                return connector.register(current -> toInactive(current, "Marked by a user as disabled")).ignoreElement().cast(Void.class);
            }
            return Mono.empty();
        }
        // Re-enable if healthy
        if (health.getHealthState() == HealthState.Healthy) {
            if (localLeadershipState == ClusterMemberLeadershipState.Disabled) {
                logger.info("Re-enabling local member which is in the disabled state");
                return connector.joinLeadershipGroup().then(connector.register(this::toActive).ignoreElement().cast(Void.class));
            }
            if (!localMember.isActive()) {
                return connector.register(this::toActive).ignoreElement().cast(Void.class);
            }
            return Mono.empty();
        }
        // Disable if unhealthy (and not the leader)
        if (localLeadershipState != ClusterMemberLeadershipState.Disabled && localLeadershipState != ClusterMemberLeadershipState.Leader) {
            logger.info("Disabling local member as it is unhealthy: {}", health);
            return connector.leaveLeadershipGroup(true).flatMap(success -> success ? connector.register(current -> toInactive(current, "Unhealthy: " + health)).ignoreElement().cast(Void.class) : Mono.empty());
        }
        if (localLeadershipState == ClusterMemberLeadershipState.Disabled && localMember.isActive()) {
            return connector.register(current -> toInactive(current, "Unhealthy: " + health)).ignoreElement().cast(Void.class);
        }
        return Mono.empty();
    }).doOnError(error -> {
        logger.info("Cluster membership health evaluation error: {}", error.getMessage());
        logger.debug("Stack trace", error);
    }).doOnTerminate(() -> {
        metrics.updateLocal(connector.getLocalLeadershipRevision().getCurrent().getLeadershipState(), healthIndicator.health());
        metrics.updateSiblings(connector.getClusterMemberSiblings());
    });
}
Also used : ExecutionContext(com.netflix.titus.common.framework.scheduler.ExecutionContext) Disposable(reactor.core.Disposable) LoggerFactory(org.slf4j.LoggerFactory) Singleton(javax.inject.Singleton) ReactorExt(com.netflix.titus.common.util.rx.ReactorExt) Function(java.util.function.Function) ScheduleReference(com.netflix.titus.common.framework.scheduler.ScheduleReference) Inject(javax.inject.Inject) ClusterMembershipService(com.netflix.titus.api.clustermembership.service.ClusterMembershipService) HealthStatus(com.netflix.titus.api.health.HealthStatus) ClusterMembershipConnector(com.netflix.titus.api.clustermembership.connector.ClusterMembershipConnector) Duration(java.time.Duration) Map(java.util.Map) Schedulers(reactor.core.scheduler.Schedulers) ClusterMember(com.netflix.titus.api.clustermembership.model.ClusterMember) ClusterMembershipRevision(com.netflix.titus.api.clustermembership.model.ClusterMembershipRevision) Logger(org.slf4j.Logger) ClusterMemberLeadershipState(com.netflix.titus.api.clustermembership.model.ClusterMemberLeadershipState) Retryers(com.netflix.titus.common.util.retry.Retryers) ClusterMemberLeadership(com.netflix.titus.api.clustermembership.model.ClusterMemberLeadership) Mono(reactor.core.publisher.Mono) ClusterMembershipServiceException(com.netflix.titus.api.clustermembership.service.ClusterMembershipServiceException) HealthIndicator(com.netflix.titus.api.health.HealthIndicator) Flux(reactor.core.publisher.Flux) ClusterMembershipEvent(com.netflix.titus.api.clustermembership.model.event.ClusterMembershipEvent) HealthState(com.netflix.titus.api.health.HealthState) ScheduleDescriptor(com.netflix.titus.common.framework.scheduler.model.ScheduleDescriptor) Optional(java.util.Optional) TitusRuntime(com.netflix.titus.common.runtime.TitusRuntime) Clock(com.netflix.titus.common.util.time.Clock) ClusterMember(com.netflix.titus.api.clustermembership.model.ClusterMember) HealthStatus(com.netflix.titus.api.health.HealthStatus) ClusterMemberLeadershipState(com.netflix.titus.api.clustermembership.model.ClusterMemberLeadershipState)

Example 7 with ClusterMember

use of com.netflix.titus.api.clustermembership.model.ClusterMember in project titus-control-plane by Netflix.

the class KubeClusterMembershipConnectorTest method doRegistrationChange.

private ClusterMembershipRevision<ClusterMember> doRegistrationChange(Supplier<ClusterMembershipRevision<ClusterMember>> action) throws InterruptedException {
    long now = titusRuntime.getClock().wallTime();
    ClusterMembershipRevision<ClusterMember> newRevision = action.get();
    assertThat(newRevision.getTimestamp()).isGreaterThanOrEqualTo(now);
    assertThat(connector.getLocalClusterMemberRevision()).isEqualTo(newRevision);
    ClusterMembershipEvent registrationEvent1 = connectorEvents.takeNext(TIMEOUT);
    assertThat(registrationEvent1).isInstanceOf(ClusterMembershipChangeEvent.class);
    assertThat(((ClusterMembershipChangeEvent) registrationEvent1).getChangeType()).isEqualTo(ClusterMembershipChangeEvent.ChangeType.Updated);
    return newRevision;
}
Also used : ClusterMember(com.netflix.titus.api.clustermembership.model.ClusterMember) ClusterMemberGenerator.activeClusterMember(com.netflix.titus.testkit.model.clustermembership.ClusterMemberGenerator.activeClusterMember) ClusterMembershipChangeEvent(com.netflix.titus.api.clustermembership.model.event.ClusterMembershipChangeEvent) ClusterMembershipEvent(com.netflix.titus.api.clustermembership.model.event.ClusterMembershipEvent)

Example 8 with ClusterMember

use of com.netflix.titus.api.clustermembership.model.ClusterMember in project titus-control-plane by Netflix.

the class MultiNodeClusterMemberResolver method buildSnapshot.

private ClusterMembershipSnapshot buildSnapshot() {
    if (memberResolversByIpAddress.isEmpty()) {
        return ClusterMembershipSnapshot.empty();
    }
    List<ClusterMembershipSnapshot> healthySnapshots = findHealthySnapshots();
    ClusterMembershipSnapshot.Builder builder = ClusterMembershipSnapshot.newBuilder();
    Map<String, List<ClusterMembershipRevision<ClusterMember>>> grouped = healthySnapshots.stream().flatMap(snapshot -> snapshot.getMemberRevisions().values().stream()).collect(Collectors.groupingBy(m -> m.getCurrent().getMemberId()));
    List<ClusterMembershipRevision<ClusterMember>> recentRevisions = grouped.values().stream().map(this::findBestMemberRevision).collect(Collectors.toList());
    builder.withMemberRevisions(recentRevisions);
    // Find leader
    Optional<ClusterMembershipRevision<ClusterMemberLeadership>> recentLeader = Optional.empty();
    for (ClusterMembershipSnapshot snapshot : healthySnapshots) {
        if (snapshot.getLeaderRevision().isPresent()) {
            if (recentLeader.isPresent()) {
                if (recentLeader.get().getRevision() < snapshot.getLeaderRevision().get().getRevision()) {
                    recentLeader = snapshot.getLeaderRevision();
                }
            } else {
                recentLeader = snapshot.getLeaderRevision();
            }
        }
    }
    recentLeader.ifPresent(builder::withLeaderRevision);
    // Choose latest version of each
    long minStaleness = healthySnapshots.stream().mapToLong(ClusterMembershipSnapshot::getStalenessMs).min().orElse(0);
    builder.withStalenessMs(minStaleness);
    return builder.build();
}
Also used : Stopwatch(com.google.common.base.Stopwatch) CollectionsExt(com.netflix.titus.common.util.CollectionsExt) LoggerFactory(org.slf4j.LoggerFactory) ClusterMembershipSnapshot(com.netflix.titus.api.clustermembership.model.ClusterMembershipSnapshot) HashMap(java.util.HashMap) ReactorExt(com.netflix.titus.common.util.rx.ReactorExt) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ConcurrentMap(java.util.concurrent.ConcurrentMap) ScheduleReference(com.netflix.titus.common.framework.scheduler.ScheduleReference) ClusterMemberAddress(com.netflix.titus.api.clustermembership.model.ClusterMemberAddress) Duration(java.time.Duration) Map(java.util.Map) ClusterMember(com.netflix.titus.api.clustermembership.model.ClusterMember) ClusterMembershipRevision(com.netflix.titus.api.clustermembership.model.ClusterMembershipRevision) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) Retryers(com.netflix.titus.common.util.retry.Retryers) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ClusterMemberLeadership(com.netflix.titus.api.clustermembership.model.ClusterMemberLeadership) Set(java.util.Set) Collectors(java.util.stream.Collectors) ReplayProcessor(reactor.core.publisher.ReplayProcessor) TimeUnit(java.util.concurrent.TimeUnit) Flux(reactor.core.publisher.Flux) List(java.util.List) ScheduleDescriptor(com.netflix.titus.common.framework.scheduler.model.ScheduleDescriptor) Optional(java.util.Optional) Preconditions(com.google.common.base.Preconditions) TitusRuntime(com.netflix.titus.common.runtime.TitusRuntime) ClusterMembershipRevision(com.netflix.titus.api.clustermembership.model.ClusterMembershipRevision) ClusterMembershipSnapshot(com.netflix.titus.api.clustermembership.model.ClusterMembershipSnapshot) ClusterMember(com.netflix.titus.api.clustermembership.model.ClusterMember) List(java.util.List)

Example 9 with ClusterMember

use of com.netflix.titus.api.clustermembership.model.ClusterMember in project titus-control-plane by Netflix.

the class ClusterMemberGenerator method clusterMemberUpdateRevision.

public static ClusterMembershipRevision<ClusterMember> clusterMemberUpdateRevision(ClusterMembershipRevision<ClusterMember> currentRevision) {
    long now = System.currentTimeMillis();
    ClusterMember current = currentRevision.getCurrent();
    return ClusterMembershipRevision.<ClusterMember>newBuilder().withCurrent(current.toBuilder().withLabels(CollectionsExt.copyAndAdd(current.getLabels(), "changedAt", "" + now)).build()).withCode("updated").withMessage("Random update to generate next revision number").withRevision(currentRevision.getRevision() + 1).withTimestamp(now).build();
}
Also used : ClusterMember(com.netflix.titus.api.clustermembership.model.ClusterMember)

Aggregations

ClusterMember (com.netflix.titus.api.clustermembership.model.ClusterMember)9 ClusterMembershipRevision (com.netflix.titus.api.clustermembership.model.ClusterMembershipRevision)5 Function (java.util.function.Function)5 ClusterMemberAddress (com.netflix.titus.api.clustermembership.model.ClusterMemberAddress)3 ClusterMemberLeadership (com.netflix.titus.api.clustermembership.model.ClusterMemberLeadership)3 ScheduleReference (com.netflix.titus.common.framework.scheduler.ScheduleReference)3 ScheduleDescriptor (com.netflix.titus.common.framework.scheduler.model.ScheduleDescriptor)3 TitusRuntime (com.netflix.titus.common.runtime.TitusRuntime)3 Retryers (com.netflix.titus.common.util.retry.Retryers)3 ReactorExt (com.netflix.titus.common.util.rx.ReactorExt)3 Duration (java.time.Duration)3 Map (java.util.Map)3 Optional (java.util.Optional)3 Logger (org.slf4j.Logger)3 LoggerFactory (org.slf4j.LoggerFactory)3 Flux (reactor.core.publisher.Flux)3 Mono (reactor.core.publisher.Mono)3 Preconditions (com.google.common.base.Preconditions)2 Stopwatch (com.google.common.base.Stopwatch)2 ClusterMembershipSnapshot (com.netflix.titus.api.clustermembership.model.ClusterMembershipSnapshot)2