use of com.netflix.titus.api.supervisor.model.MasterInstance in project titus-control-plane by Netflix.
the class ZookeeperMasterMonitorTest method testLocalMasterInstanceUpdates.
@Test(timeout = 30_000)
public void testLocalMasterInstanceUpdates() throws Exception {
// Should get dummy version first.
assertThat(masterMonitor.getCurrentMasterInstance()).isEqualTo(ZookeeperMasterMonitor.UNKNOWN_MASTER_INSTANCE);
ExtTestSubscriber<List<MasterInstance>> mastersSubscriber = new ExtTestSubscriber<>();
masterMonitor.observeMasters().subscribe(mastersSubscriber);
assertThat(mastersSubscriber.takeNext()).isEmpty();
// Update information about itself
MasterInstance initial = ZookeeperTestUtils.newMasterInstance("selfId", MasterState.Inactive);
assertThat(masterMonitor.updateOwnMasterInstance(initial).get()).isNull();
expectMasters(mastersSubscriber, initial);
// Change state
MasterInstance updated = MasterInstanceFunctions.moveTo(initial, MasterStatus.newBuilder().withState(MasterState.NonLeader).withMessage("testing").build());
assertThat(masterMonitor.updateOwnMasterInstance(updated).get()).isNull();
expectMasters(mastersSubscriber, updated);
// Now add second master
MasterInstance second = ZookeeperTestUtils.newMasterInstance("secondId", MasterState.Inactive);
addMasterInstanceToZookeeper(second);
expectMasters(mastersSubscriber, updated, second);
// And remove it
removeMasterInstanceFromZookeeper(second.getInstanceId());
expectMasters(mastersSubscriber, updated);
}
use of com.netflix.titus.api.supervisor.model.MasterInstance in project titus-control-plane by Netflix.
the class DefaultSupervisorOperations method buildEventList.
private Pair<List<SupervisorEvent>, Map<String, MasterInstance>> buildEventList(List<MasterInstance> current, Map<String, MasterInstance> state) {
Map<String, MasterInstance> newState = new HashMap<>();
current.forEach(instance -> newState.put(instance.getInstanceId(), instance));
List<SupervisorEvent> events = new ArrayList<>();
// Removed Masters
Set<String> removed = CollectionsExt.copyAndRemove(state.keySet(), newState.keySet());
removed.forEach(id -> events.add(new MasterInstanceRemovedEvent(state.get(id))));
// Added Masters
Set<String> added = CollectionsExt.copyAndRemove(newState.keySet(), state.keySet());
added.forEach(id -> events.add(new MasterInstanceUpdateEvent(newState.get(id))));
// Compare with the previous state, and build the new one
Set<String> changeCandidates = CollectionsExt.copyAndRemove(newState.keySet(), added);
changeCandidates.forEach(id -> {
if (MasterInstanceFunctions.areDifferent(newState.get(id), state.get(id))) {
events.add(new MasterInstanceUpdateEvent(newState.get(id)));
}
});
logger.debug("Master instances updated: current={}", current);
logger.debug("Master instances updated: previous={}", state.values());
logger.debug("Master instances updated: events={}", events);
return Pair.of(events, newState);
}
use of com.netflix.titus.api.supervisor.model.MasterInstance in project titus-control-plane by Netflix.
the class SupervisorServiceModule method getLocalMasterInstanceResolver.
/**
* As MasterInstance data contain a lot of details that are deployment specific, this binding is provided here
* for completeness/as an example only. It should be overridden by deployment specific configuration.
*/
@Provides
@Singleton
public LocalMasterInstanceResolver getLocalMasterInstanceResolver(SupervisorConfiguration configuration, GrpcMasterEndpointConfiguration grpcServerConfiguration, LocalMasterReadinessResolver localMasterReadinessResolver, TitusRuntime titusRuntime) {
String ipAddress = NetworkExt.getLocalIPs().flatMap(ips -> ips.stream().filter(NetworkExt::isIpV4).findFirst()).orElse("127.0.0.1");
ServerPort grpcPort = ServerPort.newBuilder().withPortNumber(grpcServerConfiguration.getPort()).withSecure(false).withProtocol("grpc").withDescription("TitusMaster GRPC endpoint").build();
MasterInstance initial = MasterInstance.newBuilder().withInstanceId(configuration.getTitusMasterInstanceId()).withInstanceGroupId(configuration.getTitusMasterInstanceId() + "Group").withIpAddress(ipAddress).withStatusHistory(Collections.emptyList()).withStatus(MasterStatus.newBuilder().withState(MasterState.Starting).withMessage("Bootstrapping").withTimestamp(titusRuntime.getClock().wallTime()).build()).withServerPorts(Collections.singletonList(grpcPort)).build();
return new DefaultLocalMasterInstanceResolver(localMasterReadinessResolver, initial);
}
use of com.netflix.titus.api.supervisor.model.MasterInstance in project titus-control-plane by Netflix.
the class LeaderElectionOrchestrator method updateOwnMasterInstanceIfChanged.
private Completable updateOwnMasterInstanceIfChanged(Optional<MasterInstance> newMasterOpt) {
if (!newMasterOpt.isPresent()) {
return Completable.complete();
}
MasterInstance newMasterInstance = newMasterOpt.get();
updateLeaderElectionState(newMasterInstance);
return masterMonitor.updateOwnMasterInstance(newMasterInstance).timeout(MASTER_STATE_UPDATE_TIMEOUT_MS, TimeUnit.MILLISECONDS, scheduler).doOnCompleted(() -> logger.info("Recorded local MasterInstance update: {}", newMasterInstance));
}
use of com.netflix.titus.api.supervisor.model.MasterInstance in project titus-control-plane by Netflix.
the class LeaderElectionOrchestrator method processChange.
private Optional<MasterInstance> processChange(Object change, MasterInstance currentMaster) {
MasterState currentState = currentMaster.getStatus().getState();
// MasterInstance update
if (change instanceof MasterInstance) {
if (MasterState.isLeader(currentState)) {
// If already a leader, ignore further updates
return Optional.empty();
}
return Optional.of((MasterInstance) change);
}
// Leader election event
if (change instanceof MasterState) {
MasterState newState = (MasterState) change;
if (!MasterState.isLeader(newState)) {
titusRuntime.getCodeInvariants().inconsistent("Expected leader election state, but got: %s", newState);
return Optional.empty();
}
if (!MasterState.isAfter(currentState, newState)) {
titusRuntime.getCodeInvariants().inconsistent("Unexpected leader election state: current=%s, new=%s", currentState, newState);
return Optional.empty();
}
MasterInstance newMasterInstance = currentMaster.toBuilder().withStatus(MasterStatus.newBuilder().withState(newState).withMessage("Leader activation status change").withTimestamp(titusRuntime.getClock().wallTime()).build()).withStatusHistory(CollectionsExt.copyAndAdd(currentMaster.getStatusHistory(), currentMaster.getStatus())).build();
return Optional.of(newMasterInstance);
}
return Optional.empty();
}
Aggregations