/** * @return Previous Baseline topology. */ @Nullable public BaselineTopology previousBaselineTopology() { return prevState != null ? prevState.baselineTopology() : null; }
/** * @return {@code True} if cluster was in active state. */ boolean clusterActive() { return state.active() && !state.transition(); } }
/** * Creates a non-transitional cluster state. This method effectively cleans all fields identifying the * state as transitional and creates a new state with the state transition result. * * @param success Transition success status. * @return Cluster state that finished transition. */ public DiscoveryDataClusterState finish(boolean success) { return success ? new DiscoveryDataClusterState( null, active, baselineTopology, null, null, null ) : prevState != null ? prevState : DiscoveryDataClusterState.createState(false, null); }
/** */ private void onStateRestored(BaselineTopology blt) { DiscoveryDataClusterState state = globalState; if (!state.active() && !state.transition() && state.baselineTopology() == null) { DiscoveryDataClusterState newState = DiscoveryDataClusterState.createState(false, blt); globalState = newState; } }
compatibilityMode = false; if (state.transition()) { if (isApplicable(msg, state)) { GridChangeGlobalStateFuture fut = changeStateFuture(msg); final GridChangeGlobalStateFuture stateFut = changeStateFuture(msg); GridFutureAdapter<Void> transitionFut = transitionFuts.get(state.transitionRequestId()); globalState.baselineTopology()); globalState = DiscoveryDataClusterState.createTransitionState( prevState, msg.activate(), msg.activate() ? msg.baselineTopology() : prevState.baselineTopology(), msg.requestId(), topVer, globalState.setTransitionResult(msg.requestId(), msg.activate()); StateChangeRequest req = new StateChangeRequest(msg, bltHistItem, msg.activate() != state.active(), stateChangeTopVer);
/** {@inheritDoc} */ @Override @Nullable public IgniteInternalFuture<Boolean> onLocalJoin(DiscoCache discoCache) { final DiscoveryDataClusterState state = globalState; if (state.active()) checkLocalNodeInBaseline(state.baselineTopology()); if (state.transition()) { joinFut = new TransitionOnJoinWaitFuture(state, discoCache); return joinFut; } else if (!ctx.clientNode() && !ctx.isDaemon() && ctx.config().isAutoActivationEnabled() && !state.active() && isBaselineSatisfied(state.baselineTopology(), discoCache.serverNodes())) changeGlobalState0(true, state.baselineTopology(), false); return null; }
/** * @param msg State change message. * @param state Current cluster state. * @return {@code True} if states are equivalent. */ protected static boolean isEquivalent(ChangeGlobalStateMessage msg, DiscoveryDataClusterState state) { return (msg.activate() == state.active() && BaselineTopology.equals(msg.baselineTopology(), state.baselineTopology())); }
if (globalState.transition() && globalState.active()) { Boolean transitionRes = globalState.transitionResult(); GridFutureAdapter<Void> fut = transitionFuts.get(globalState.transitionRequestId()); if (fut != null) { if (asyncWaitForTransition) { return new IgniteFinishedFutureImpl<>(globalState.baselineChanged()); transitionRes = globalState.transitionResult(); return new IgniteFinishedFutureImpl<>(globalState.active());
/** {@inheritDoc} */ @Override public void onGridDataReceived(DiscoveryDataBag.GridDiscoveryData data) { if (data.commonData() instanceof DiscoveryDataClusterState) { if (globalState != null && globalState.baselineTopology() != null) //node with BaselineTopology is not allowed to join mixed cluster // (where some nodes don't support BaselineTopology) throw new IgniteException("Node with BaselineTopology cannot join" + " mixed cluster running in compatibility mode"); globalState = (DiscoveryDataClusterState) data.commonData(); compatibilityMode = true; return; } BaselineStateAndHistoryData stateDiscoData = (BaselineStateAndHistoryData)data.commonData(); if (stateDiscoData != null) { DiscoveryDataClusterState state = stateDiscoData.globalState; if (state.transition()) transitionFuts.put(state.transitionRequestId(), new GridFutureAdapter<Void>()); globalState = state; if (stateDiscoData.recentHistory != null) { for (BaselineTopologyHistoryItem item : stateDiscoData.recentHistory.history()) bltHist.bufferHistoryItemForStore(item); } } }
if (globalState.baselineTopology() != null) { String msg = "Node not supporting BaselineTopology" + " is not allowed to join the cluster with BaselineTopology"; if (joiningNodeState == null || joiningNodeState.baselineTopology() == null) return null; if (globalState == null || globalState.baselineTopology() == null) { if (joiningNodeState != null && joiningNodeState.baselineTopology() != null) { String msg = "Node with set up BaselineTopology is not allowed to join cluster without one: " + node.consistentId(); if (globalState.transition() && globalState.previousBaselineTopology() == null) { if (globalState.transition()) clusterBlt = globalState.previousBaselineTopology(); else clusterBlt = globalState.baselineTopology(); BaselineTopology joiningNodeBlt = joiningNodeState.baselineTopology();
/** Whether cluster is active at this moment or not. Also returns {@code true} if cluster is being activated. */ private boolean isActive() { return ctx.state().clusterState().active(); }
/** * * @return {@code True} If baseLine changed, {@code False} if not. */ public boolean baselineChanged() { BaselineTopology prevBLT = previousBaselineTopology(); BaselineTopology curBLT = baselineTopology(); if (prevBLT == null && curBLT != null) return true; if (prevBLT!= null && curBLT != null) return !prevBLT.equals(curBLT); return false; }
/** {@inheritDoc} */ @Override @Nullable public ChangeGlobalStateFinishMessage onNodeLeft(ClusterNode node) { if (globalState.transition()) { Set<UUID> nodes = globalState.transitionNodes(); if (nodes.remove(node.id()) && nodes.isEmpty()) { U.warn(log, "Failed to change cluster state, all participating nodes failed. " + "Switching to inactive state."); ChangeGlobalStateFinishMessage msg = new ChangeGlobalStateFinishMessage(globalState.transitionRequestId(), false, false); onStateFinishMessage(msg); return msg; } } return null; }
/** * @param state Current state. * @param discoCache Discovery data cache. */ TransitionOnJoinWaitFuture(DiscoveryDataClusterState state, DiscoCache discoCache) { assert state.transition() : state; transitionNodes = U.newHashSet(state.transitionNodes().size()); for (UUID nodeId : state.transitionNodes()) { if (discoCache.node(nodeId) != null) transitionNodes.add(nodeId); } }
/** {@inheritDoc} */ @Override public void onStateFinishMessage(ChangeGlobalStateFinishMessage msg) { DiscoveryDataClusterState state = globalState; if (msg.requestId().equals(state.transitionRequestId())) { log.info("Received state change finish message: " + msg.clusterActive()); globalState = state.finish(msg.success()); afterStateChangeFinished(msg.id(), msg.success()); ctx.cache().onStateChangeFinish(msg); TransitionOnJoinWaitFuture joinFut = this.joinFut; if (joinFut != null) joinFut.onDone(false); GridFutureAdapter<Void> transitionFut = transitionFuts.remove(state.transitionRequestId()); if (transitionFut != null) { state.setTransitionResult(msg.requestId(), msg.clusterActive()); transitionFut.onDone(); } } else U.warn(log, "Received state finish message with unexpected ID: " + msg); }
/** {@inheritDoc} */ @Override public Map<Integer, CacheMetrics> cacheMetrics() { try { if (disableCacheMetricsUpdate) return Collections.emptyMap(); /** Caches should not be accessed while state transition is in progress. */ if (ctx.state().clusterState().transition()) return Collections.emptyMap(); Collection<GridCacheAdapter<?, ?>> caches = ctx.cache().internalCaches(); if (!F.isEmpty(caches)) { Map<Integer, CacheMetrics> metrics = U.newHashMap(caches.size()); for (GridCacheAdapter<?, ?> cache : caches) { if (cache.context().statisticsEnabled() && cache.context().started() && cache.context().affinity().affinityTopologyVersion().topologyVersion() > 0) metrics.put(cache.context().cacheId(), cache.localMetrics()); } return metrics; } } catch (Exception e) { U.warn(log, "Failed to compute cache metrics", e); } return Collections.emptyMap(); } };
/** {@inheritDoc} */ @Override public boolean isNodeInBaseline() { ClusterNode locNode = localNode(); if (locNode.isClient() || locNode.isDaemon()) return false; DiscoveryDataClusterState clusterState = ctx.state().clusterState(); return clusterState.hasBaselineTopology() && CU.baselineNode(locNode, clusterState); }
/** * @param active Current status. * @return State instance. */ static DiscoveryDataClusterState createState(boolean active, @Nullable BaselineTopology baselineTopology) { return new DiscoveryDataClusterState(null, active, baselineTopology, null, null, null); }
/** {@inheritDoc} */ @Override public DiscoveryDataClusterState pendingState(ChangeGlobalStateMessage stateMsg) { return DiscoveryDataClusterState.createState(stateMsg.activate() || stateMsg.forceChangeBaselineTopology(), stateMsg.baselineTopology()); }
compatibilityMode = false; if (state.transition()) { if (isApplicable(msg, state)) { GridChangeGlobalStateFuture fut = changeStateFuture(msg); final GridChangeGlobalStateFuture stateFut = changeStateFuture(msg); GridFutureAdapter<Void> transitionFut = transitionFuts.get(state.transitionRequestId()); globalState.baselineTopology()); globalState = DiscoveryDataClusterState.createTransitionState( prevState, msg.activate(), msg.activate() ? msg.baselineTopology() : prevState.baselineTopology(), msg.requestId(), topVer, globalState.setTransitionResult(msg.requestId(), msg.activate()); StateChangeRequest req = new StateChangeRequest(msg, bltHistItem, msg.activate() != state.active(), stateChangeTopVer);