mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 17:51:21 +00:00
Merge pull request #2361 from weaveworks/change-instance-fix
Clear client polling and nodes state on dismount
This commit is contained in:
@@ -17,7 +17,7 @@ import {
|
||||
getNodeDetails,
|
||||
getTopologies,
|
||||
deletePipe,
|
||||
stopTopologyPolling,
|
||||
stopPolling,
|
||||
teardownWebsockets,
|
||||
} from '../utils/web-api-utils';
|
||||
import { getCurrentTopologyUrl } from '../utils/topology-utils';
|
||||
@@ -720,20 +720,17 @@ export function toggleTroubleshootingMenu(ev) {
|
||||
|
||||
export function changeInstance() {
|
||||
return (dispatch, getState) => {
|
||||
dispatch({ type: ActionTypes.CHANGE_INSTANCE });
|
||||
dispatch({
|
||||
type: ActionTypes.CHANGE_INSTANCE
|
||||
});
|
||||
updateRoute(getState);
|
||||
const state = getState();
|
||||
getTopologies(activeTopologyOptionsSelector(state), dispatch);
|
||||
getNodesDelta(
|
||||
getCurrentTopologyUrl(state),
|
||||
activeTopologyOptionsSelector(state),
|
||||
dispatch,
|
||||
true // forces websocket teardown and reconnect to new instance
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function shutdown() {
|
||||
stopTopologyPolling();
|
||||
stopPolling();
|
||||
teardownWebsockets();
|
||||
return {
|
||||
type: ActionTypes.SHUTDOWN
|
||||
};
|
||||
}
|
||||
|
||||
@@ -42,9 +42,10 @@ class App extends React.Component {
|
||||
window.addEventListener('keyup', this.onKeyUp);
|
||||
|
||||
getRouter(this.props.dispatch, this.props.urlState).start({hashbang: true});
|
||||
if (!this.props.routeSet) {
|
||||
// dont request topologies when already done via router
|
||||
getTopologies(this.props.activeTopologyOptions, this.props.dispatch);
|
||||
if (!this.props.routeSet || process.env.WEAVE_CLOUD) {
|
||||
// dont request topologies when already done via router.
|
||||
// If running as a component, always request topologies when the app mounts.
|
||||
getTopologies(this.props.activeTopologyOptions, this.props.dispatch, true);
|
||||
}
|
||||
getApiDetails(this.props.dispatch);
|
||||
}
|
||||
@@ -52,7 +53,7 @@ class App extends React.Component {
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('keypress', this.onKeyPress);
|
||||
window.removeEventListener('keyup', this.onKeyUp);
|
||||
shutdown();
|
||||
this.props.dispatch(shutdown());
|
||||
}
|
||||
|
||||
onKeyUp(ev) {
|
||||
|
||||
@@ -62,6 +62,7 @@ const ACTION_TYPES = [
|
||||
'SET_GRID_MODE',
|
||||
'CHANGE_INSTANCE',
|
||||
'TOGGLE_CONTRAST_MODE',
|
||||
'SHUTDOWN'
|
||||
];
|
||||
|
||||
export default zipObject(ACTION_TYPES, ACTION_TYPES);
|
||||
|
||||
@@ -744,6 +744,11 @@ export function rootReducer(state = initialState, action) {
|
||||
return state.set('contrastMode', action.enabled);
|
||||
}
|
||||
|
||||
case ActionTypes.SHUTDOWN: {
|
||||
state = clearNodes(state);
|
||||
return state.set('nodesLoaded', false);
|
||||
}
|
||||
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ let apiDetailsTimer = 0;
|
||||
let controlErrorTimer = 0;
|
||||
let createWebsocketAt = 0;
|
||||
let firstMessageOnWebsocketAt = 0;
|
||||
let continuePolling = true;
|
||||
|
||||
export function buildOptionsQuery(options) {
|
||||
if (options) {
|
||||
@@ -111,9 +112,11 @@ function createWebsocket(topologyUrl, optionsQuery, dispatch) {
|
||||
socket = null;
|
||||
dispatch(closeWebsocket());
|
||||
|
||||
reconnectTimer = setTimeout(() => {
|
||||
createWebsocket(topologyUrl, optionsQuery, dispatch);
|
||||
}, reconnectTimerInterval);
|
||||
if (continuePolling) {
|
||||
reconnectTimer = setTimeout(() => {
|
||||
createWebsocket(topologyUrl, optionsQuery, dispatch);
|
||||
}, reconnectTimerInterval);
|
||||
}
|
||||
};
|
||||
|
||||
socket.onerror = () => {
|
||||
@@ -172,35 +175,44 @@ export function getAllNodes(getState, dispatch) {
|
||||
Promise.resolve());
|
||||
}
|
||||
|
||||
export function getTopologies(options, dispatch) {
|
||||
export function getTopologies(options, dispatch, initialPoll) {
|
||||
// Used to resume polling when navigating between pages in Weave Cloud.
|
||||
continuePolling = initialPoll === true ? true : continuePolling;
|
||||
clearTimeout(topologyTimer);
|
||||
const optionsQuery = buildOptionsQuery(options);
|
||||
const url = `${getApiPath()}/api/topology?${optionsQuery}`;
|
||||
doRequest({
|
||||
url,
|
||||
success: (res) => {
|
||||
dispatch(receiveTopologies(res));
|
||||
topologyTimer = setTimeout(() => {
|
||||
getTopologies(options, dispatch);
|
||||
}, TOPOLOGY_INTERVAL);
|
||||
if (continuePolling) {
|
||||
dispatch(receiveTopologies(res));
|
||||
topologyTimer = setTimeout(() => {
|
||||
getTopologies(options, dispatch);
|
||||
}, TOPOLOGY_INTERVAL);
|
||||
}
|
||||
},
|
||||
error: (err) => {
|
||||
log(`Error in topology request: ${err.responseText}`);
|
||||
error: (req) => {
|
||||
log(`Error in topology request: ${req.responseText}`);
|
||||
dispatch(receiveError(url));
|
||||
topologyTimer = setTimeout(() => {
|
||||
getTopologies(options, dispatch);
|
||||
}, TOPOLOGY_INTERVAL);
|
||||
// Only retry in stand-alone mode
|
||||
if (continuePolling) {
|
||||
topologyTimer = setTimeout(() => {
|
||||
getTopologies(options, dispatch);
|
||||
}, TOPOLOGY_INTERVAL);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function getNodesDelta(topologyUrl, options, dispatch, forceReload) {
|
||||
export function getNodesDelta(topologyUrl, options, dispatch) {
|
||||
const optionsQuery = buildOptionsQuery(options);
|
||||
// Only recreate websocket if url changed or if forced (weave cloud instance reload);
|
||||
// Check for truthy options and that options have changed.
|
||||
const isNewOptions = currentOptions && currentOptions !== optionsQuery;
|
||||
const isNewUrl = topologyUrl && (topologyUrl !== currentUrl || isNewOptions);
|
||||
if (forceReload || isNewUrl) {
|
||||
const isNewUrl = topologyUrl !== currentUrl || isNewOptions;
|
||||
// `topologyUrl` can be undefined initially, so only create a socket if it is truthy
|
||||
// and no socket exists, or if we get a new url.
|
||||
if ((topologyUrl && !socket) || (topologyUrl && isNewUrl)) {
|
||||
createWebsocket(topologyUrl, optionsQuery, dispatch);
|
||||
currentUrl = topologyUrl;
|
||||
currentOptions = optionsQuery;
|
||||
@@ -250,16 +262,20 @@ export function getApiDetails(dispatch) {
|
||||
url,
|
||||
success: (res) => {
|
||||
dispatch(receiveApiDetails(res));
|
||||
apiDetailsTimer = setTimeout(() => {
|
||||
getApiDetails(dispatch);
|
||||
}, API_INTERVAL);
|
||||
if (continuePolling) {
|
||||
apiDetailsTimer = setTimeout(() => {
|
||||
getApiDetails(dispatch);
|
||||
}, API_INTERVAL);
|
||||
}
|
||||
},
|
||||
error: (err) => {
|
||||
log(`Error in api details request: ${err.responseText}`);
|
||||
error: (req) => {
|
||||
log(`Error in api details request: ${req.responseText}`);
|
||||
receiveError(url);
|
||||
apiDetailsTimer = setTimeout(() => {
|
||||
getApiDetails(dispatch);
|
||||
}, API_INTERVAL / 2);
|
||||
if (continuePolling) {
|
||||
apiDetailsTimer = setTimeout(() => {
|
||||
getApiDetails(dispatch);
|
||||
}, API_INTERVAL / 2);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -353,9 +369,10 @@ export function getPipeStatus(pipeId, dispatch) {
|
||||
});
|
||||
}
|
||||
|
||||
export function stopTopologyPolling() {
|
||||
export function stopPolling() {
|
||||
clearTimeout(apiDetailsTimer);
|
||||
clearTimeout(topologyTimer);
|
||||
topologyTimer = 0;
|
||||
continuePolling = false;
|
||||
}
|
||||
|
||||
export function teardownWebsockets() {
|
||||
|
||||
Reference in New Issue
Block a user