From 77e23e295ce499079a1597e46e106644dcddd66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Fri, 20 Dec 2019 20:25:59 +0000 Subject: [PATCH] fix(ui): retry all fetch GET calls --- ui/src/Common/Fetch.js | 20 ++++++++++++++++--- .../ManagedSilence/DeleteSilence.test.js | 7 ++++--- .../NavBar/FilterInput/index.test.js | 4 ++-- ui/src/Stores/AlertStore.js | 11 +--------- ui/src/setupTests.js | 5 +++++ 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/ui/src/Common/Fetch.js b/ui/src/Common/Fetch.js index ab8214b2a..fb09d84c1 100644 --- a/ui/src/Common/Fetch.js +++ b/ui/src/Common/Fetch.js @@ -1,12 +1,26 @@ import merge from "lodash/merge"; +import promiseRetry from "promise-retry"; + const CommonOptions = { credentials: "include", redirect: "follow" }; -const FetchGet = async (uri, options) => - await fetch(uri, merge({}, { method: "GET" }, CommonOptions, options)); +const FetchRetryConfig = { + retries: 5, + minTimeout: 1000, + maxTimeout: 5000 +}; + +const FetchGet = async (uri, options, retryOptions) => + await promiseRetry( + (retry, number) => + fetch(uri, merge({}, { method: "GET" }, CommonOptions, options)).catch( + retry + ), + FetchRetryConfig + ); const FetchPost = async (uri, options) => await fetch(uri, merge({}, { method: "POST" }, CommonOptions, options)); @@ -14,4 +28,4 @@ const FetchPost = async (uri, options) => const FetchDelete = async (uri, options) => await fetch(uri, merge({}, { method: "DELETE" }, CommonOptions, options)); -export { CommonOptions, FetchGet, FetchPost, FetchDelete }; +export { CommonOptions, FetchGet, FetchPost, FetchDelete, FetchRetryConfig }; diff --git a/ui/src/Components/ManagedSilence/DeleteSilence.test.js b/ui/src/Components/ManagedSilence/DeleteSilence.test.js index d33e27c70..520341727 100644 --- a/ui/src/Components/ManagedSilence/DeleteSilence.test.js +++ b/ui/src/Components/ManagedSilence/DeleteSilence.test.js @@ -18,7 +18,7 @@ beforeEach(() => { silenceFormStore = new SilenceFormStore(); cluster = "am"; silence = MockSilence(); - fetch.mockResponseOnce(JSON.stringify(MockAPIResponse())); + fetch.mockResponse(JSON.stringify(MockAPIResponse())); alertStore.data.upstreams = { instances: [ @@ -127,8 +127,9 @@ describe("", () => { expect(tree.find("LabelSetList")).toHaveLength(1); }); - it("fetches affected alerts on mount", () => { - MountedDeleteSilenceModalContent(); + it("fetches affected alerts on mount", async () => { + const tree = MountedDeleteSilenceModalContent(); + await expect(tree.instance().previewState.fetch).resolves.toBeUndefined(); expect(fetch).toHaveBeenCalled(); }); diff --git a/ui/src/Components/NavBar/FilterInput/index.test.js b/ui/src/Components/NavBar/FilterInput/index.test.js index f9c73baf2..79cf862d7 100644 --- a/ui/src/Components/NavBar/FilterInput/index.test.js +++ b/ui/src/Components/NavBar/FilterInput/index.test.js @@ -196,14 +196,14 @@ describe("", () => { }); it("handles failed suggestion fetches", async () => { - fetch.mockRejectOnce("Fetch error"); + fetch.mockReject("Fetch error"); const tree = MountedInput(); const instance = tree.instance(); tree.find("input").simulate("change", { target: { value: "bar" } }); await WaitForFetch(tree); - expect(fetch.mock.calls).toHaveLength(1); + expect(fetch.mock.calls).toHaveLength(6); expect(fetch.mock.calls[0]).toContain("./autocomplete.json?term=bar"); expect(instance.inputStore.suggestions).toHaveLength(0); }); diff --git a/ui/src/Stores/AlertStore.js b/ui/src/Stores/AlertStore.js index 911622542..8b57f8520 100644 --- a/ui/src/Stores/AlertStore.js +++ b/ui/src/Stores/AlertStore.js @@ -8,8 +8,6 @@ import qs from "qs"; import moment from "moment"; -import promiseRetry from "promise-retry"; - import { FetchGet } from "Common/Fetch"; const QueryStringEncodeOptions = { @@ -260,11 +258,6 @@ class AlertStore { constructor(initialFilters) { this.filters.setFilters(initialFilters); - this.retryConfig = { - retries: 5, - minTimeout: 1000, - maxTimeout: 5000 - }; } fetch = action((sortOrder, sortLabel, sortReverse) => { @@ -275,9 +268,7 @@ class AlertStore { `alerts.json?sortOrder=${sortOrder}&sortLabel=${sortLabel}&sortReverse=${sortReverse}&` ) + FormatAPIFilterQuery(this.filters.values.map(f => f.raw)); - return promiseRetry((retry, number) => { - return FetchGet(alertsURI, {}).catch(retry); - }, this.retryConfig) + return FetchGet(alertsURI, {}) .then(result => { this.status.setProcessing(); return result.json(); diff --git a/ui/src/setupTests.js b/ui/src/setupTests.js index 0b158a653..908477a8d 100644 --- a/ui/src/setupTests.js +++ b/ui/src/setupTests.js @@ -1,6 +1,8 @@ import Enzyme from "enzyme"; import Adapter from "enzyme-adapter-react-16"; +import { FetchRetryConfig } from "Common/Fetch"; + // https://github.com/airbnb/enzyme Enzyme.configure({ adapter: new Adapter() }); @@ -27,3 +29,6 @@ for (const level of ["error", "warn", "info", "log", "trace"]) { } }; } + +FetchRetryConfig.minTimeout = 2; +FetchRetryConfig.maxTimeout = 10;