Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clear client polling and nodes state on dismount #2361

Merged
merged 1 commit into from
Mar 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions client/app/scripts/actions/app-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
getNodeDetails,
getTopologies,
deletePipe,
stopTopologyPolling,
stopPolling,
teardownWebsockets,
} from '../utils/web-api-utils';
import { getCurrentTopologyUrl } from '../utils/topology-utils';
Expand Down Expand Up @@ -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
};
}
9 changes: 5 additions & 4 deletions client/app/scripts/components/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,18 @@ 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);
}

componentWillUnmount() {
window.removeEventListener('keypress', this.onKeyPress);
window.removeEventListener('keyup', this.onKeyUp);
shutdown();
this.props.dispatch(shutdown());
}

onKeyUp(ev) {
Expand Down
1 change: 1 addition & 0 deletions client/app/scripts/constants/action-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const ACTION_TYPES = [
'SET_GRID_MODE',
'CHANGE_INSTANCE',
'TOGGLE_CONTRAST_MODE',
'SHUTDOWN'
];

export default zipObject(ACTION_TYPES, ACTION_TYPES);
5 changes: 5 additions & 0 deletions client/app/scripts/reducers/root.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
69 changes: 43 additions & 26 deletions client/app/scripts/utils/web-api-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 = () => {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
});
}
Expand Down Expand Up @@ -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() {
Expand Down