diff --git a/client/app/scripts/actions/app-actions.js b/client/app/scripts/actions/app-actions.js index 89b44722a..740175de1 100644 --- a/client/app/scripts/actions/app-actions.js +++ b/client/app/scripts/actions/app-actions.js @@ -17,6 +17,8 @@ import { getNodeDetails, getTopologies, deletePipe, + stopTopologyPolling, + teardownWebsockets, } from '../utils/web-api-utils'; import { getCurrentTopologyUrl } from '../utils/topology-utils'; import { storageSet } from '../utils/storage-utils'; @@ -735,3 +737,8 @@ export function changeInstance() { ); }; } + +export function shutdown() { + stopTopologyPolling(); + teardownWebsockets(); +} diff --git a/client/app/scripts/components/app.js b/client/app/scripts/components/app.js index 43970c0ef..adc1251f4 100644 --- a/client/app/scripts/components/app.js +++ b/client/app/scripts/components/app.js @@ -13,7 +13,7 @@ import Topologies from './topologies'; import TopologyOptions from './topology-options'; import { getApiDetails, getTopologies } from '../utils/web-api-utils'; import { focusSearch, pinNextMetric, hitBackspace, hitEnter, hitEsc, unpinMetric, - selectMetric, toggleHelp, toggleGridMode } from '../actions/app-actions'; + selectMetric, toggleHelp, toggleGridMode, shutdown } from '../actions/app-actions'; import Details from './details'; import Nodes from './nodes'; import GridModeSelector from './grid-mode-selector'; @@ -52,6 +52,7 @@ class App extends React.Component { componentWillUnmount() { window.removeEventListener('keypress', this.onKeyPress); window.removeEventListener('keyup', this.onKeyUp); + shutdown(); } onKeyUp(ev) { diff --git a/client/app/scripts/utils/router-utils.js b/client/app/scripts/utils/router-utils.js index 6bc7d330c..35dbae03b 100644 --- a/client/app/scripts/utils/router-utils.js +++ b/client/app/scripts/utils/router-utils.js @@ -90,21 +90,20 @@ export function updateRoute(getState) { export function getRouter(dispatch, initialState) { + let mergedState = initialState; // strip any trailing '/'s. page.base(window.location.pathname.replace(/\/$/, '')); + const storageState = storageGet(STORAGE_STATE_KEY); + if (storageState) { + window.location.hash = `!/state/${storageState}`; + const parsedState = JSON.parse(decodeURL(storageState)); + mergedState = Object.assign(initialState, parsedState); + } + page('/', () => { // recover from storage state on empty URL - const storageState = storageGet(STORAGE_STATE_KEY); - if (storageState) { - // push storage state to URL - window.location.hash = `!/state/${storageState}`; - const parsedState = JSON.parse(decodeURL(storageState)); - const mergedState = Object.assign(initialState, parsedState); - dispatch(route(mergedState)); - } else { - dispatch(route(initialState)); - } + dispatch(route(mergedState)); }); page('/state/:state', (ctx) => { diff --git a/client/app/scripts/utils/web-api-utils.js b/client/app/scripts/utils/web-api-utils.js index 70cf089cd..f7ab99c5b 100644 --- a/client/app/scripts/utils/web-api-utils.js +++ b/client/app/scripts/utils/web-api-utils.js @@ -142,7 +142,10 @@ function createWebsocket(topologyUrl, optionsQuery, dispatch) { * Any opts that get passed in will override the defaults. */ function doRequest(opts) { - const config = defaults(opts, { contentType: 'application/json' }); + const config = defaults(opts, { + contentType: 'application/json', + type: 'json' + }); if (csrfToken) { config.headers = Object.assign({}, config.headers, { 'X-CSRF-Token': csrfToken }); } @@ -193,9 +196,10 @@ export function getTopologies(options, dispatch) { export function getNodesDelta(topologyUrl, options, dispatch, forceReload) { const optionsQuery = buildOptionsQuery(options); - // only recreate websocket if url changed or if forced (weave cloud instance reload); - const isNewUrl = topologyUrl && (topologyUrl !== currentUrl || currentOptions !== optionsQuery); - + // 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) { createWebsocket(topologyUrl, optionsQuery, dispatch); currentUrl = topologyUrl; @@ -348,3 +352,18 @@ export function getPipeStatus(pipeId, dispatch) { } }); } + +export function stopTopologyPolling() { + clearTimeout(topologyTimer); + topologyTimer = 0; +} + +export function teardownWebsockets() { + clearTimeout(reconnectTimer); + if (socket) { + socket.onerror = null; + socket.onclose = null; + socket.close(); + currentOptions = null; + } +}