diff --git a/.env b/.env index 6b8a2bf18..cda058d2e 100644 --- a/.env +++ b/.env @@ -22,6 +22,7 @@ REACT_APP_UI_WINDOW_ID=curiosity REACT_APP_AJAX_TIMEOUT=60000 REACT_APP_AJAX_CACHE=30000 +REACT_APP_SELECTOR_CACHE=120000 REACT_APP_CONFIG_SERVICE_LOCALES_COOKIE=rh_locale REACT_APP_CONFIG_SERVICE_LOCALES_DEFAULT_LNG=en-US diff --git a/src/redux/selectors/graphCardSelectors.js b/src/redux/selectors/graphCardSelectors.js index b502f2a0a..cf33e185f 100644 --- a/src/redux/selectors/graphCardSelectors.js +++ b/src/redux/selectors/graphCardSelectors.js @@ -1,4 +1,5 @@ import { createSelector } from 'reselect'; +import LruCache from 'lru-cache'; import moment from 'moment'; import _isEqual from 'lodash/isEqual'; import _camelCase from 'lodash/camelCase'; @@ -10,9 +11,14 @@ import { apiQueries } from '../common'; * Selector cache. * * @private - * @type {{dataId: {string}, data: {object}}} + * @type {object} */ -const selectorCache = { dataId: null, data: {} }; +const selectorCache = new LruCache({ + maxAge: Number.parseInt(process.env.REACT_APP_SELECTOR_CACHE, 10), + max: 10, + stale: true, + updateAgeOnGet: true +}); /** * Return a combined state, props object. @@ -71,15 +77,10 @@ const selector = createSelector([statePropsFilter, queryFilter], (response, quer const responseMetaQuery = { ...metaQuery }; - const cachedGranularity = - (viewId && productId && selectorCache.data[`${viewId}_${productId}_${JSON.stringify(query)}`]) || undefined; - - Object.assign(updatedResponseData, { ...cachedGranularity }); + const cache = + (viewId && productId && selectorCache.get(`${viewId}_${productId}_${JSON.stringify(query)}`)) || undefined; - if (viewId && selectorCache.dataId !== viewId) { - selectorCache.dataId = viewId; - selectorCache.data = {}; - } + Object.assign(updatedResponseData, { ...cache }); if (responseData.fulfilled && productId === metaId && _isEqual(query, responseMetaQuery)) { const [report, capacity] = responseData.data; @@ -169,9 +170,7 @@ const selector = createSelector([statePropsFilter, queryFilter], (response, quer // Update response and cache updatedResponseData.fulfilled = true; - selectorCache.data[`${viewId}_${productId}_${JSON.stringify(query)}`] = { - ...updatedResponseData - }; + selectorCache.set(`${viewId}_${productId}_${JSON.stringify(query)}`, { ...updatedResponseData }); } return updatedResponseData; diff --git a/src/redux/selectors/inventoryListSelectors.js b/src/redux/selectors/inventoryListSelectors.js index 27e367f87..215829750 100644 --- a/src/redux/selectors/inventoryListSelectors.js +++ b/src/redux/selectors/inventoryListSelectors.js @@ -1,4 +1,5 @@ import { createSelectorCreator, defaultMemoize } from 'reselect'; +import LruCache from 'lru-cache'; import _isEqual from 'lodash/isEqual'; import { rhsmApiTypes } from '../../types/rhsmApiTypes'; import { reduxHelpers } from '../common/reduxHelpers'; @@ -17,9 +18,14 @@ const createDeepEqualSelector = createSelectorCreator(defaultMemoize, _isEqual); * Selector cache. * * @private - * @type {{dataId: {string}, data: {object}}} + * @type {object} */ -const selectorCache = { dataId: null, data: {} }; +const selectorCache = new LruCache({ + maxAge: Number.parseInt(process.env.REACT_APP_SELECTOR_CACHE, 10), + max: 10, + stale: true, + updateAgeOnGet: true +}); /** * Return a combined state, props object. @@ -88,16 +94,10 @@ const selector = createDeepEqualSelector([statePropsFilter, queryFilter], (respo }; const cache = - (viewId && productId && selectorCache.data[`${viewId}_${productId}_${JSON.stringify(query)}`]) || undefined; + (viewId && productId && selectorCache.get(`${viewId}_${productId}_${JSON.stringify(query)}`)) || undefined; Object.assign(updatedResponseData, { ...cache }); - // Reset cache on viewId update - if (viewId && selectorCache.dataId !== viewId) { - selectorCache.dataId = viewId; - selectorCache.data = {}; - } - if (responseData.fulfilled && productId === metaId && _isEqual(query, metaQuery)) { const { [rhsmApiTypes.RHSM_API_RESPONSE_INVENTORY_DATA]: listData = [], @@ -139,9 +139,7 @@ const selector = createDeepEqualSelector([statePropsFilter, queryFilter], (respo updatedResponseData.itemCount = meta[rhsmApiTypes.RHSM_API_RESPONSE_META_TYPES.COUNT] ?? 0; updatedResponseData.listData = updatedListData; updatedResponseData.fulfilled = true; - selectorCache.data[`${viewId}_${productId}_${JSON.stringify(query)}`] = { - ...updatedResponseData - }; + selectorCache.set(`${viewId}_${productId}_${JSON.stringify(query)}`, { ...updatedResponseData }); } return updatedResponseData; diff --git a/src/redux/selectors/subscriptionsListSelectors.js b/src/redux/selectors/subscriptionsListSelectors.js index 82f380823..fbd901f1f 100644 --- a/src/redux/selectors/subscriptionsListSelectors.js +++ b/src/redux/selectors/subscriptionsListSelectors.js @@ -1,4 +1,5 @@ import { createSelectorCreator, defaultMemoize } from 'reselect'; +import LruCache from 'lru-cache'; import _isEqual from 'lodash/isEqual'; import { rhsmApiTypes } from '../../types/rhsmApiTypes'; import { reduxHelpers } from '../common/reduxHelpers'; @@ -23,9 +24,14 @@ const createDeepEqualSelector = createSelectorCreator(defaultMemoize, _isEqual); * Selector cache. * * @private - * @type {{dataId: {string}, data: {object}}} + * @type {object} */ -const selectorCache = { dataId: null, data: {} }; +const selectorCache = new LruCache({ + maxAge: Number.parseInt(process.env.REACT_APP_SELECTOR_CACHE, 10), + max: 10, + stale: true, + updateAgeOnGet: true +}); /** * Return a combined state, props object. @@ -87,16 +93,10 @@ const selector = createDeepEqualSelector([statePropsFilter, queryFilter], (respo }; const cache = - (viewId && productId && selectorCache.data[`${viewId}_${productId}_${JSON.stringify(query)}`]) || undefined; + (viewId && productId && selectorCache.get(`${viewId}_${productId}_${JSON.stringify(query)}`)) || undefined; Object.assign(updatedResponseData, { ...cache }); - // Reset cache on viewId update - if (viewId && selectorCache.dataId !== viewId) { - selectorCache.dataId = viewId; - selectorCache.data = {}; - } - if (responseData.fulfilled && productId === metaId && _isEqual(query, metaQuery)) { const { [rhsmApiTypes.RHSM_API_RESPONSE_INVENTORY_DATA]: listData = [], @@ -134,9 +134,7 @@ const selector = createDeepEqualSelector([statePropsFilter, queryFilter], (respo updatedResponseData.itemCount = meta[rhsmApiTypes.RHSM_API_RESPONSE_META_TYPES.COUNT] ?? 0; updatedResponseData.listData = updatedListData; updatedResponseData.fulfilled = true; - selectorCache.data[`${viewId}_${productId}_${JSON.stringify(query)}`] = { - ...updatedResponseData - }; + selectorCache.set(`${viewId}_${productId}_${JSON.stringify(query)}`, { ...updatedResponseData }); } return updatedResponseData;