diff --git a/frontend/src/Store/Actions/appActions.js b/frontend/src/Store/Actions/appActions.js index d19bffe06..aff536cef 100644 --- a/frontend/src/Store/Actions/appActions.js +++ b/frontend/src/Store/Actions/appActions.js @@ -1,7 +1,9 @@ import _ from 'lodash'; import { createAction } from 'redux-actions'; +import createAjaxRequest from 'Utilities/createAjaxRequest'; import getSectionState from 'Utilities/State/getSectionState'; import updateSectionState from 'Utilities/State/updateSectionState'; +import { createThunk, handleThunks } from 'Store/thunks'; import createHandleActions from './Creators/createHandleActions'; function getDimensions(width, height) { @@ -22,6 +24,8 @@ function getDimensions(width, height) { export const section = 'app'; const messagesSection = 'app.messages'; +let abortPingServer = null; +let pingTimeout = null; // // State @@ -50,6 +54,8 @@ export const SET_VERSION = 'app/setVersion'; export const SET_APP_VALUE = 'app/setAppValue'; export const SET_IS_SIDEBAR_VISIBLE = 'app/setIsSidebarVisible'; +export const PING_SERVER = 'app/pingServer'; + // // Action Creators @@ -59,6 +65,70 @@ export const setIsSidebarVisible = createAction(SET_IS_SIDEBAR_VISIBLE); export const setAppValue = createAction(SET_APP_VALUE); export const showMessage = createAction(SHOW_MESSAGE); export const hideMessage = createAction(HIDE_MESSAGE); +export const pingServer = createThunk(PING_SERVER); + +// +// Helpers + +function pingServerAfterTimeout(getState, dispatch) { + if (abortPingServer) { + abortPingServer(); + abortPingServer = null; + } + + if (pingTimeout) { + clearTimeout(pingTimeout); + pingTimeout = null; + } + + pingTimeout = setTimeout(() => { + if (!getState().isRestarting && getState().isConnected) { + return; + } + + const ajaxOptions = { + url: '/system/status', + method: 'GET', + contentType: 'application/json' + }; + + const { request, abortRequest } = createAjaxRequest(ajaxOptions); + + abortPingServer = abortRequest; + + request.done(() => { + abortPingServer = null; + pingTimeout = null; + + dispatch(setAppValue({ + isRestarting: false + })); + }); + + request.fail((xhr) => { + abortPingServer = null; + pingTimeout = null; + + // Unauthorized, but back online + if (xhr.status === 401) { + dispatch(setAppValue({ + isRestarting: false + })); + } else { + pingServerAfterTimeout(getState, dispatch); + } + }); + }, 5000); +} + +// +// Action Handlers + +export const actionHandlers = handleThunks({ + [PING_SERVER]: function(getState, payload, dispatch) { + pingServerAfterTimeout(getState, dispatch); + } +}); // // Reducers @@ -135,4 +205,3 @@ export const reducers = createHandleActions({ } }, defaultState, section); - diff --git a/frontend/src/Store/Actions/systemActions.js b/frontend/src/Store/Actions/systemActions.js index d238a92f1..6e007c853 100644 --- a/frontend/src/Store/Actions/systemActions.js +++ b/frontend/src/Store/Actions/systemActions.js @@ -10,6 +10,7 @@ import createFetchHandler from './Creators/createFetchHandler'; import createRemoveItemHandler from './Creators/createRemoveItemHandler'; import createHandleActions from './Creators/createHandleActions'; import createServerSideCollectionHandlers from './Creators/createServerSideCollectionHandlers'; +import { pingServer } from './appActions'; import { set } from './baseActions'; // @@ -351,6 +352,7 @@ export const actionHandlers = handleThunks({ promise.done(() => { dispatch(setAppValue({ isRestarting: true })); + dispatch(pingServer()); }); },