mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-24 07:46:41 +00:00
Merge pull request #2828 from weaveworks/update-topology-data-when-time-travelling
Update topologies and namespaces when time travelling
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Map as makeMap } from 'immutable';
|
||||
import { Set as makeSet, Map as makeMap } from 'immutable';
|
||||
import includes from 'lodash/includes';
|
||||
|
||||
import { trackMixpanelEvent } from '../utils/tracking-utils';
|
||||
@@ -73,9 +73,27 @@ class TopologyOptions extends React.Component {
|
||||
renderOption(option) {
|
||||
const { activeOptions, currentTopologyId } = this.props;
|
||||
const optionId = option.get('id');
|
||||
const activeValue = activeOptions && activeOptions.has(optionId)
|
||||
? activeOptions.get(optionId)
|
||||
: option.get('defaultValue');
|
||||
|
||||
// Make the active value be the intersection of the available options
|
||||
// and the active selection and use the default value if there is no
|
||||
// overlap. It seems intuitive that active selection would always be a
|
||||
// subset of available option, but the exception can happen when going
|
||||
// back in time (making available options change, while not touching
|
||||
// the selection).
|
||||
// TODO: This logic should probably be made consistent with how topology
|
||||
// selection is handled when time travelling, especially when the name-
|
||||
// spaces are brought under category selection.
|
||||
// TODO: Consider extracting this into a global selector.
|
||||
let activeValue = option.get('defaultValue');
|
||||
if (activeOptions && activeOptions.has(optionId)) {
|
||||
const activeSelection = makeSet(activeOptions.get(optionId));
|
||||
const availableOptions = makeSet(option.get('options').map(o => o.get('value')));
|
||||
const intersection = activeSelection.intersect(availableOptions);
|
||||
if (!intersection.isEmpty()) {
|
||||
activeValue = intersection.toJS();
|
||||
}
|
||||
}
|
||||
|
||||
const noneItem = makeMap({
|
||||
value: '',
|
||||
label: option.get('noneLabel')
|
||||
|
||||
@@ -223,7 +223,7 @@ export function rootReducer(state = initialState, action) {
|
||||
if (topology) {
|
||||
const topologyId = topology.get('parentId') || topology.get('id');
|
||||
const optionKey = ['topologyOptions', topologyId, action.option];
|
||||
const currentOption = state.getIn(['topologyOptions', topologyId, action.option]);
|
||||
const currentOption = state.getIn(optionKey);
|
||||
|
||||
if (!isEqual(currentOption, action.value)) {
|
||||
state = clearNodes(state);
|
||||
|
||||
@@ -103,6 +103,12 @@ export function getApiPath(pathname = window.location.pathname) {
|
||||
return basePath(pathname);
|
||||
}
|
||||
|
||||
function topologiesUrl(state) {
|
||||
const activeTopologyOptions = activeTopologyOptionsSelector(state);
|
||||
const optionsQuery = buildUrlQuery(activeTopologyOptions, state);
|
||||
return `${getApiPath()}/api/topology?${optionsQuery}`;
|
||||
}
|
||||
|
||||
export function getWebsocketUrl(host = window.location.host, pathname = window.location.pathname) {
|
||||
const wsProto = location.protocol === 'https:' ? 'wss' : 'ws';
|
||||
return `${wsProto}://${host}${process.env.SCOPE_API_PREFIX || ''}${basePath(pathname)}`;
|
||||
@@ -235,20 +241,19 @@ export function getResourceViewNodesSnapshot(state, dispatch) {
|
||||
getNodesForTopologies(state, dispatch, topologyIds);
|
||||
}
|
||||
|
||||
// NOTE: getState is called every time to make sure the up-to-date state is used.
|
||||
export function getTopologies(getState, dispatch, initialPoll = false) {
|
||||
function pollTopologies(getState, dispatch, initialPoll = false) {
|
||||
// Used to resume polling when navigating between pages in Weave Cloud.
|
||||
continuePolling = initialPoll === true ? true : continuePolling;
|
||||
clearTimeout(topologyTimer);
|
||||
const optionsQuery = buildUrlQuery(activeTopologyOptionsSelector(getState()), getState());
|
||||
const url = `${getApiPath()}/api/topology?${optionsQuery}`;
|
||||
// NOTE: getState is called every time to make sure the up-to-date state is used.
|
||||
const url = topologiesUrl(getState());
|
||||
doRequest({
|
||||
url,
|
||||
success: (res) => {
|
||||
if (continuePolling && !isPausedSelector(getState())) {
|
||||
dispatch(receiveTopologies(res));
|
||||
topologyTimer = setTimeout(() => {
|
||||
getTopologies(getState, dispatch);
|
||||
pollTopologies(getState, dispatch);
|
||||
}, TOPOLOGY_REFRESH_INTERVAL);
|
||||
}
|
||||
},
|
||||
@@ -258,13 +263,27 @@ export function getTopologies(getState, dispatch, initialPoll = false) {
|
||||
// Only retry in stand-alone mode
|
||||
if (continuePolling && !isPausedSelector(getState())) {
|
||||
topologyTimer = setTimeout(() => {
|
||||
getTopologies(getState, dispatch);
|
||||
pollTopologies(getState, dispatch);
|
||||
}, TOPOLOGY_REFRESH_INTERVAL);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getTopologiesOnce(getState, dispatch) {
|
||||
const url = topologiesUrl(getState());
|
||||
doRequest({
|
||||
url,
|
||||
success: (res) => {
|
||||
dispatch(receiveTopologies(res));
|
||||
},
|
||||
error: (req) => {
|
||||
log(`Error in topology request: ${req.responseText}`);
|
||||
dispatch(receiveError(url));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateWebsocketChannel(getState, dispatch, forceRequest) {
|
||||
const topologyUrl = getCurrentTopologyUrl(getState());
|
||||
const topologyOptions = activeTopologyOptionsSelector(getState());
|
||||
@@ -325,6 +344,14 @@ export function getNodeDetails(getState, dispatch) {
|
||||
}
|
||||
}
|
||||
|
||||
export function getTopologies(getState, dispatch, forceRequest) {
|
||||
if (isPausedSelector(getState())) {
|
||||
getTopologiesOnce(getState, dispatch);
|
||||
} else {
|
||||
pollTopologies(getState, dispatch, forceRequest);
|
||||
}
|
||||
}
|
||||
|
||||
export function getNodes(getState, dispatch, forceRequest = false) {
|
||||
if (isPausedSelector(getState())) {
|
||||
getNodesOnce(getState, dispatch);
|
||||
|
||||
Reference in New Issue
Block a user