use of com.yahoo.vespa.clustercontroller.core.NodeInfo in project vespa by vespa-engine.
the class DatabaseHandler method loadWantedStates.
public boolean loadWantedStates(Context context) throws InterruptedException {
log.log(LogLevel.DEBUG, "Fleetcontroller " + nodeIndex + ": Retrieving node wanted states.");
synchronized (databaseMonitor) {
if (database != null && !database.isClosed()) {
currentlyStored.wantedStates = database.retrieveWantedStates();
}
}
Map<Node, NodeState> wantedStates = currentlyStored.wantedStates;
if (wantedStates == null) {
if (usingZooKeeper()) {
log.log(LogLevel.WARNING, "Fleetcontroller " + nodeIndex + ": Failed to retrieve wanted states from ZooKeeper. Assuming UP for all nodes.");
}
wantedStates = new TreeMap<>();
}
boolean altered = false;
for (Node node : wantedStates.keySet()) {
NodeInfo nodeInfo = context.getCluster().getNodeInfo(node);
// ignore wanted state of nodes which doesn't exist
if (nodeInfo == null)
continue;
NodeState wantedState = wantedStates.get(node);
if (!nodeInfo.getUserWantedState().equals(wantedState)) {
nodeInfo.setWantedState(wantedState);
context.getNodeStateUpdateListener().handleNewWantedNodeState(nodeInfo, wantedState);
altered = true;
}
log.log(LogLevel.DEBUG, "Fleetcontroller " + nodeIndex + ": Node " + node + " has wanted state " + wantedState);
}
// Remove wanted state from any node having a wanted state set that is no longer valid
for (NodeInfo info : context.getCluster().getNodeInfo()) {
NodeState wantedState = wantedStates.get(info.getNode());
if (wantedState == null && !info.getUserWantedState().equals(new NodeState(info.getNode().getType(), State.UP))) {
info.setWantedState(null);
context.getNodeStateUpdateListener().handleNewWantedNodeState(info, info.getWantedState().clone());
altered = true;
}
}
return altered;
}
use of com.yahoo.vespa.clustercontroller.core.NodeInfo in project vespa by vespa-engine.
the class DatabaseHandler method saveWantedStates.
public void saveWantedStates(Context context) throws InterruptedException {
log.log(LogLevel.DEBUG, "Fleetcontroller " + nodeIndex + ": Checking whether wanted states have changed compared to zookeeper version.");
Map<Node, NodeState> wantedStates = new TreeMap<>();
for (NodeInfo info : context.getCluster().getNodeInfo()) {
if (!info.getUserWantedState().equals(new NodeState(info.getNode().getType(), State.UP))) {
wantedStates.put(info.getNode(), info.getUserWantedState());
}
}
// - The value is different from the value we know is stored.
if (pendingStore.wantedStates != null || currentlyStored.wantedStates == null || !currentlyStored.wantedStates.equals(wantedStates)) {
log.log(LogLevel.DEBUG, "Fleetcontroller " + nodeIndex + ": Scheduling new wanted states to be stored into zookeeper.");
pendingStore.wantedStates = wantedStates;
doNextZooKeeperTask(context);
}
}
use of com.yahoo.vespa.clustercontroller.core.NodeInfo in project vespa by vespa-engine.
the class SetNodeStateRequest method setWantedState.
static SetResponse setWantedState(ContentCluster cluster, SetUnitStateRequest.Condition condition, Map<String, UnitState> newStates, Node node, NodeStateOrHostInfoChangeHandler stateListener, ClusterState currentClusterState) throws StateRestApiException {
if (!cluster.hasConfiguredNode(node.getIndex())) {
throw new MissingIdException(cluster.getName(), node);
}
NodeInfo nodeInfo = cluster.getNodeInfo(node);
if (nodeInfo == null)
throw new IllegalArgumentException("Cannot set the wanted state of unknown node " + node);
NodeState wantedState = nodeInfo.getUserWantedState();
NodeState newWantedState = getRequestedNodeState(newStates, node);
NodeStateChangeChecker.Result result = cluster.calculateEffectOfNewState(node, currentClusterState, condition, wantedState, newWantedState);
log.log(LogLevel.DEBUG, "node=" + node + " current-cluster-state=" + // Includes version in output format
currentClusterState + " condition=" + condition + " wanted-state=" + wantedState + " new-wanted-state=" + newWantedState + " change-check=" + result);
boolean success = setWantedStateAccordingToResult(result, newWantedState, condition, nodeInfo, cluster, stateListener);
// If the state was successfully set, just return an "ok" message back.
String reason = success ? "ok" : result.getReason();
return new SetResponse(reason, success);
}
use of com.yahoo.vespa.clustercontroller.core.NodeInfo in project vespa by vespa-engine.
the class SlobrokClient method updateCluster.
public boolean updateCluster(ContentCluster cluster, NodeAddedOrRemovedListener listener) {
if (mirror == null)
return false;
int mirrorVersion = mirror.updates();
if (freshMirror) {
freshMirror = false;
} else if (cluster.getSlobrokGenerationCount() == mirrorVersion) {
if (log.isLoggable(LogLevel.SPAM)) {
log.log(LogLevel.SPAM, "Slobrok still at generation count " + cluster.getSlobrokGenerationCount() + ". Not updating.");
}
return false;
}
// Set to unused value until we are done processing info.
cluster.setSlobrokGenerationCount(0);
Map<Node, SlobrokData> distributorRpc = getSlobrokData("storage/cluster." + cluster.getName() + "/distributor/*");
Map<Node, SlobrokData> distributorMbus = getSlobrokData("storage/cluster." + cluster.getName() + "/distributor/*/default");
Map<Node, SlobrokData> storageRpc = getSlobrokData("storage/cluster." + cluster.getName() + "/storage/*");
Map<Node, SlobrokData> storageMbus = getSlobrokData("storage/cluster." + cluster.getName() + "/storage/*/default");
Map<Node, SlobrokData> slobrokNodes = new TreeMap<>();
for (SlobrokData data : distributorRpc.values()) {
if (distributorMbus.containsKey(data.node)) {
slobrokNodes.put(data.node, data);
}
}
for (SlobrokData data : storageRpc.values()) {
if (storageMbus.containsKey(data.node)) {
slobrokNodes.put(data.node, data);
}
}
List<SlobrokData> newNodes = new LinkedList<>();
List<NodeInfo> missingNodeInfos = new LinkedList<>();
List<SlobrokData> alteredRpcAddressNodes = new LinkedList<>();
List<NodeInfo> returningNodeInfos = new LinkedList<>();
detectNewAndMissingNodes(cluster, slobrokNodes, newNodes, missingNodeInfos, alteredRpcAddressNodes, returningNodeInfos);
for (SlobrokData data : newNodes) {
// XXX we really would like to cross-check the actual RPC address against what's configured,
// but this information does not seem to be available to the cluster controller currently.
NodeInfo nodeInfo = cluster.clusterInfo().getNodeInfo(data.node);
// slobrok may contain nonconfigured nodes during state transitions
if (nodeInfo == null)
continue;
cluster.clusterInfo().setRpcAddress(data.node, data.rpcAddress);
if (listener != null)
// TODO: We'll never add new nodes here, move this to where clusterInfo.setNodes is called?
listener.handleNewNode(nodeInfo);
}
for (NodeInfo nodeInfo : missingNodeInfos) {
nodeInfo.markRpcAddressOutdated(timer);
if (listener != null)
listener.handleMissingNode(nodeInfo);
}
for (SlobrokData data : alteredRpcAddressNodes) {
// TODO: Abort the current node state requests? See NodeInfo.abortCurrentNodeStateRequests()
NodeInfo nodeInfo = cluster.clusterInfo().setRpcAddress(data.node, data.rpcAddress);
if (listener != null) {
// TODO: We'll never add new nodes here, move this to where clusterInfo.setNodes is called?
listener.handleNewRpcAddress(nodeInfo);
}
}
for (NodeInfo nodeInfo : returningNodeInfos) {
nodeInfo.markRpcAddressLive();
nodeInfo.abortCurrentNodeStateRequests();
if (listener != null) {
listener.handleReturnedRpcAddress(nodeInfo);
}
}
cluster.setSlobrokGenerationCount(mirrorVersion);
for (NodeInfo nodeInfo : cluster.getNodeInfo()) {
if (slobrokNodes.containsKey(nodeInfo.getNode()) && nodeInfo.isRpcAddressOutdated()) {
log.log(LogLevel.WARNING, "Node " + nodeInfo + " was tagged NOT in slobrok even though it is. It was in the following lists:" + (newNodes.contains(nodeInfo.getNode()) ? " newNodes" : "") + (missingNodeInfos.contains(nodeInfo) ? " missingNodes" : "") + (alteredRpcAddressNodes.contains(nodeInfo.getNode()) ? " alteredNodes" : "") + (returningNodeInfos.contains(nodeInfo) ? " returningNodes" : ""));
nodeInfo.markRpcAddressLive();
}
}
log.log(LogLevel.SPAM, "Slobrok information updated to generation " + cluster.getSlobrokGenerationCount());
return true;
}
use of com.yahoo.vespa.clustercontroller.core.NodeInfo in project vespa by vespa-engine.
the class SetNodeStateRequestTest method testSetStateRequest.
private void testSetStateRequest(String wantedStateString, State storageWantedState, State distributorWantedState, NodeStateChangeChecker.Result result, Optional<State> expectedNewStorageWantedState, Optional<State> expectedNewDistributorWantedState) throws StateRestApiException {
when(cluster.hasConfiguredNode(NODE_INDEX)).thenReturn(true);
NodeInfo storageNodeInfo = mock(NodeInfo.class);
when(cluster.getNodeInfo(storageNode)).thenReturn(storageNodeInfo);
NodeState storageNodeState = new NodeState(NodeType.STORAGE, storageWantedState);
when(storageNodeInfo.getUserWantedState()).thenReturn(storageNodeState);
when(unitState.getId()).thenReturn(wantedStateString);
when(unitState.getReason()).thenReturn(REASON);
when(cluster.calculateEffectOfNewState(any(), any(), any(), any(), any())).thenReturn(result);
when(storageNodeInfo.isStorage()).thenReturn(storageNode.getType() == NodeType.STORAGE);
when(storageNodeInfo.getNodeIndex()).thenReturn(storageNode.getIndex());
NodeInfo distributorNodeInfo = mock(NodeInfo.class);
Node distributorNode = new Node(NodeType.DISTRIBUTOR, NODE_INDEX);
when(cluster.getNodeInfo(distributorNode)).thenReturn(distributorNodeInfo);
NodeState distributorNodeState = new NodeState(distributorNode.getType(), distributorWantedState);
when(distributorNodeInfo.getUserWantedState()).thenReturn(distributorNodeState);
setWantedState();
if (expectedNewStorageWantedState.isPresent()) {
NodeState expectedNewStorageNodeState = new NodeState(NodeType.STORAGE, expectedNewStorageWantedState.get());
verify(storageNodeInfo).setWantedState(expectedNewStorageNodeState);
verify(stateListener).handleNewWantedNodeState(storageNodeInfo, expectedNewStorageNodeState);
}
if (expectedNewDistributorWantedState.isPresent()) {
NodeState expectedNewDistributorNodeState = new NodeState(NodeType.DISTRIBUTOR, expectedNewDistributorWantedState.get());
verify(distributorNodeInfo).setWantedState(expectedNewDistributorNodeState);
verify(stateListener).handleNewWantedNodeState(distributorNodeInfo, expectedNewDistributorNodeState);
}
}
Aggregations