From a611cd03d8d6b1e6269898e4d3af5fe077991bdc Mon Sep 17 00:00:00 2001 From: cartcrom <39385577+cartcrom@users.noreply.github.com> Date: Wed, 30 Nov 2022 15:37:48 -0500 Subject: [PATCH] fix: add retries to relay network layer (#5485) * implemented relay modern * cleaned up relay env * added max number of retries * remove caching layer * fixed sparkline caching * updated retry vars * moved delay backoff logic into sep function * inlined beforeRetry * deduplicated * added custom error middleware * added custom error middleware * empty array * update * clear errors * only if errors exist * check length * fix: create empty data on error * fix: rm unnecessary types * fix: rm unnecessary import * fix: return empty data if res.errors * fix: clear errors but do ont throw * fix: use noThrow * retry explicit array * reordered middleware Co-authored-by: Vignesh Mohankumar Co-authored-by: Zach Pomerantz --- package.json | 1 + src/graphql/data/RelayEnvironment.ts | 49 +++++++++++++++++++++++++--- src/graphql/data/fetchGraphQL.ts | 28 ---------------- yarn.lock | 15 ++++++++- 4 files changed, 60 insertions(+), 33 deletions(-) delete mode 100644 src/graphql/data/fetchGraphQL.ts diff --git a/package.json b/package.json index 1f87f1a098..619a2730dc 100644 --- a/package.json +++ b/package.json @@ -212,6 +212,7 @@ "react-query": "^3.39.1", "react-redux": "^8.0.2", "react-relay": "^14.1.0", + "react-relay-network-modern": "^6.2.1", "react-router-dom": "^6.3.0", "react-spring": "^9.5.5", "react-table": "^7.8.0", diff --git a/src/graphql/data/RelayEnvironment.ts b/src/graphql/data/RelayEnvironment.ts index beef878e97..b1dcec3a7e 100644 --- a/src/graphql/data/RelayEnvironment.ts +++ b/src/graphql/data/RelayEnvironment.ts @@ -1,7 +1,11 @@ import ms from 'ms.macro' -import { Environment, Network, RecordSource, Store } from 'relay-runtime' - -import fetchGraphQL from './fetchGraphQL' +import { + RelayNetworkLayer, + RelayNetworkLayerResponse, + retryMiddleware, + urlMiddleware, +} from 'react-relay-network-modern' +import { Environment, RecordSource, Store } from 'relay-runtime' // This makes it possible (and more likely) to be able to reuse data when navigating back to a page, // tab or piece of content that has been visited before. These settings together configure the cache @@ -9,8 +13,45 @@ import fetchGraphQL from './fetchGraphQL' const gcReleaseBufferSize = 250 const queryCacheExpirationTime = ms`5m` +const GRAPHQL_URL = process.env.REACT_APP_AWS_API_ENDPOINT +if (!GRAPHQL_URL) { + throw new Error('AWS URL MISSING FROM ENVIRONMENT') +} + +const RETRY_TIME_MS = [3200, 6400, 12800] + +// This network layer must not cache, or it will break cache-evicting network policies +const network = new RelayNetworkLayer( + [ + urlMiddleware({ + url: GRAPHQL_URL, + headers: { + 'Content-Type': 'application/json', + }, + }), + function logAndIgnoreErrors(next) { + return async (req) => { + try { + const res = await next(req) + if (!res || !res.data) throw new Error('Missing response data') + return res + } catch (e) { + console.error(e) + return RelayNetworkLayerResponse.createFromGraphQL({ data: [] }) + } + } + }, + retryMiddleware({ + fetchTimeout: ms`30s`, // mirrors backend's timeout in case that fails + retryDelays: RETRY_TIME_MS, + statusCodes: (statusCode) => statusCode >= 500 && statusCode < 600, + }), + ], + { noThrow: true } +) + export const CachingEnvironment = new Environment({ - network: Network.create(fetchGraphQL), + network, store: new Store(new RecordSource(), { gcReleaseBufferSize, queryCacheExpirationTime }), }) export default CachingEnvironment diff --git a/src/graphql/data/fetchGraphQL.ts b/src/graphql/data/fetchGraphQL.ts deleted file mode 100644 index dcb7fa3597..0000000000 --- a/src/graphql/data/fetchGraphQL.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Variables } from 'react-relay' -import { GraphQLResponse, RequestParameters } from 'relay-runtime' - -const GRAPHQL_URL = process.env.REACT_APP_AWS_API_ENDPOINT - -if (!GRAPHQL_URL) { - throw new Error('AWS URL MISSING FROM ENVIRONMENT') -} - -const headers = { - 'Content-Type': 'application/json', -} - -const fetchQuery = (params: RequestParameters, variables: Variables): Promise => { - const body = JSON.stringify({ - query: params.text, // GraphQL text from input - variables, - }) - - return fetch(GRAPHQL_URL, { method: 'POST', body, headers }) - .then((res) => res.json()) - .catch((e) => { - console.error(e) - return { data: [] } - }) -} - -export default fetchQuery diff --git a/yarn.lock b/yarn.lock index 7ed442c6e0..b8a049c466 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7130,7 +7130,7 @@ core-js-pure@^3.16.0: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.24.1.tgz#8839dde5da545521bf282feb7dc6d0b425f39fd3" integrity sha512-r1nJk41QLLPyozHUUPmILCEMtMw24NG4oWK6RbsDdjzQgg9ZvrUsPBj1MnG0wXXp1DCDU6j+wUvEmBSrtRbLXg== -core-js@3.6.5, core-js@^3.6.5: +core-js@3.6.5: version "3.6.5" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== @@ -7140,6 +7140,11 @@ core-js@^2.4.0: resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== +core-js@^3.0.0, core-js@^3.6.5: + version "3.26.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.26.1.tgz#7a9816dabd9ee846c1c0fe0e8fcad68f3709134e" + integrity sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA== + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -14959,6 +14964,14 @@ react-refresh@^0.8.3: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== +react-relay-network-modern@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/react-relay-network-modern/-/react-relay-network-modern-6.2.1.tgz#34e93110cf1bb0e666bffb00b513335c37950bc9" + integrity sha512-O1kP9GkNrm4d+ibfuTY9yNbkXV6vAByJ4jYTZIXn8nh7jLWoe6PneF1VcBYvYvzWYsebpCLDQHDPoXI05S+rhQ== + dependencies: + core-js "^3.0.0" + extract-files "^9.0.0" + react-relay@^14.1.0: version "14.1.0" resolved "https://registry.yarnpkg.com/react-relay/-/react-relay-14.1.0.tgz#2a2349d33ca6558543340a12b363ee2de3db06a6"