From 846fe18d04b2c59a95f19a1d51ac631d6da7f9a8 Mon Sep 17 00:00:00 2001 From: Luca Stauble Date: Fri, 28 Apr 2023 17:50:52 +0200 Subject: [PATCH 1/2] fix: set a longer interval between failing NoOp requests --- src/network/fetch.ts | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/network/fetch.ts b/src/network/fetch.ts index ea7602b7..945f2aae 100644 --- a/src/network/fetch.ts +++ b/src/network/fetch.ts @@ -20,6 +20,18 @@ import { IS_STANDALONE, SHELL_APP_ID } from '../constants'; import { useNetworkStore } from '../store/network'; import { handleSync } from '../store/network/utils'; +/** + * Polling interval to use if the long polling delay + * is not allowed for the user + */ +const POLLING_NOWAIT_INTERVAL = 10_000; + +/** + * Polling interval to use if a previous request failed + * with a 500 error + */ +const POLLING_RETRY_INTERVAL = 60_000; + export const fetchNoOp = (): void => { // eslint-disable-next-line @typescript-eslint/no-use-before-define getSoapFetch(SHELL_APP_ID)( @@ -91,8 +103,28 @@ const normalizeContext = (context: any): SoapContext => { return context; }; +/** + * Return the polling interval for the next NoOp request. + * The interval length depends on the user settings, but it can be + * overridden by the server response/errors + * @param res + */ +const getPollingInterval = (res: SoapResponse): number => { + const { pollingInterval } = useNetworkStore.getState(); + const waitDisallowed = (res?.Body as { waitDisallowed?: number })?.waitDisallowed; + const fault = res?.Body?.Fault; + if (fault) { + return POLLING_RETRY_INTERVAL; + } + if (waitDisallowed) { + return POLLING_NOWAIT_INTERVAL; + } + + return pollingInterval; +}; + const handleResponse = (api: string, res: SoapResponse): R | ErrorSoapBodyResponse => { - const { pollingInterval, noOpTimeout } = useNetworkStore.getState(); + const { noOpTimeout } = useNetworkStore.getState(); const { usedQuota } = useAccountStore.getState(); clearTimeout(noOpTimeout); if (res.Body.Fault) { @@ -126,9 +158,8 @@ const handleResponse = (api: string, res: SoapResponse): R | ErrorSoapBody useAccountStore.setState({ usedQuota: responseUsedQuota ?? usedQuota }); - const nextPollingInterval = (res?.Body as { waitDisallowed?: number })?.waitDisallowed - ? 10000 - : pollingInterval; + + const nextPollingInterval = getPollingInterval(res); useNetworkStore.setState({ noOpTimeout: setTimeout(() => fetchNoOp(), nextPollingInterval), pollingInterval: nextPollingInterval, From ea81c899491555452fc8b682cd553309e0380174 Mon Sep 17 00:00:00 2001 From: gabriele Date: Fri, 28 Apr 2023 18:24:44 +0200 Subject: [PATCH 2/2] fix: reset polling interval to the user default setting when a request does not fail --- src/network/fetch.ts | 34 +----------------------- src/network/get-info.ts | 18 ++----------- src/store/network/utils.ts | 53 +++++++++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 50 deletions(-) diff --git a/src/network/fetch.ts b/src/network/fetch.ts index 945f2aae..8e1979d0 100644 --- a/src/network/fetch.ts +++ b/src/network/fetch.ts @@ -18,19 +18,7 @@ import { report } from '../reporting'; import { useAccountStore } from '../store/account'; import { IS_STANDALONE, SHELL_APP_ID } from '../constants'; import { useNetworkStore } from '../store/network'; -import { handleSync } from '../store/network/utils'; - -/** - * Polling interval to use if the long polling delay - * is not allowed for the user - */ -const POLLING_NOWAIT_INTERVAL = 10_000; - -/** - * Polling interval to use if a previous request failed - * with a 500 error - */ -const POLLING_RETRY_INTERVAL = 60_000; +import { getPollingInterval, handleSync } from '../store/network/utils'; export const fetchNoOp = (): void => { // eslint-disable-next-line @typescript-eslint/no-use-before-define @@ -103,26 +91,6 @@ const normalizeContext = (context: any): SoapContext => { return context; }; -/** - * Return the polling interval for the next NoOp request. - * The interval length depends on the user settings, but it can be - * overridden by the server response/errors - * @param res - */ -const getPollingInterval = (res: SoapResponse): number => { - const { pollingInterval } = useNetworkStore.getState(); - const waitDisallowed = (res?.Body as { waitDisallowed?: number })?.waitDisallowed; - const fault = res?.Body?.Fault; - if (fault) { - return POLLING_RETRY_INTERVAL; - } - if (waitDisallowed) { - return POLLING_NOWAIT_INTERVAL; - } - - return pollingInterval; -}; - const handleResponse = (api: string, res: SoapResponse): R | ErrorSoapBodyResponse => { const { noOpTimeout } = useNetworkStore.getState(); const { usedQuota } = useAccountStore.getState(); diff --git a/src/network/get-info.ts b/src/network/get-info.ts index beb469b6..3301a8b9 100644 --- a/src/network/get-info.ts +++ b/src/network/get-info.ts @@ -8,25 +8,11 @@ import { filter } from 'lodash'; import { SHELL_APP_ID } from '../constants'; import { useAppStore } from '../store/app'; import { normalizeAccount } from '../store/account/normalization'; -import { AccountSettings, GetInfoResponse, CarbonioModule } from '../../types'; +import { GetInfoResponse, CarbonioModule } from '../../types'; import { getSoapFetch } from './fetch'; import { useAccountStore } from '../store/account'; import { useNetworkStore } from '../store/network'; - -const parsePollingInterval = (settings: AccountSettings): number => { - const pollingPref = (settings.prefs?.zimbraPrefMailPollingInterval ?? '') as string; - if (pollingPref === '500') { - return 500; - } - const pollingValue = parseInt(pollingPref, 10); - if (Number.isNaN(pollingValue)) { - return 30000; - } - if (pollingPref.includes('m')) { - return pollingValue * 60 * 1000; - } - return pollingValue * 1000; -}; +import { parsePollingInterval } from '../store/network/utils'; export const getInfo = (): Promise => fetch('/static/iris/components.json') diff --git a/src/store/network/utils.ts b/src/store/network/utils.ts index 91a11f8c..251bb4a0 100644 --- a/src/store/network/utils.ts +++ b/src/store/network/utils.ts @@ -5,11 +5,62 @@ */ import { forEach } from 'lodash'; -import { SoapContext } from '../../../types'; +import { AccountSettings, SoapContext, SoapResponse } from '../../../types'; import { folderWorker, tagWorker } from '../../workers'; import { useFolderStore } from '../folder'; import { useTagStore } from '../tags'; import { useNetworkStore } from './store'; +import { useAccountStore } from '../account'; + +/** + * Polling interval to use if the long polling delay + * is not allowed for the user + */ +const POLLING_NOWAIT_INTERVAL = 10_000; + +/** + * Polling interval to use if a previous request failed + * with a 500 error + */ +const POLLING_RETRY_INTERVAL = 60_000; + +export const parsePollingInterval = (settings: AccountSettings): number => { + const pollingPref = (settings.prefs?.zimbraPrefMailPollingInterval ?? '') as string; + if (pollingPref === '500') { + return 500; + } + const pollingValue = parseInt(pollingPref, 10); + if (Number.isNaN(pollingValue)) { + return 30000; + } + if (pollingPref.includes('m')) { + return pollingValue * 60 * 1000; + } + return pollingValue * 1000; +}; + +/** + * Return the polling interval for the next NoOp request. + * The interval length depends on the user settings, but it can be + * overridden by the server response/errors + * @param res + */ +export const getPollingInterval = (res: SoapResponse): number => { + const { pollingInterval } = useNetworkStore.getState(); + const { settings } = useAccountStore.getState(); + const waitDisallowed = (res?.Body as { waitDisallowed?: number })?.waitDisallowed; + const fault = res?.Body?.Fault; + if (fault) { + return POLLING_RETRY_INTERVAL; + } + if (waitDisallowed) { + return POLLING_NOWAIT_INTERVAL; + } + if (!fault) { + return parsePollingInterval(settings); + } + return pollingInterval; +}; export const handleSync = ({ refresh, notify }: SoapContext): Promise => new Promise((r) => {