Load config errors less often

If we encounter network delays loading the config errors endpoint
(which is likely if it's large), then we can end up issuing multiple
outstanding GET requests for the same endpoint.  Avoid that by using
the isFetching pattern used by other members of the store.

Also, store the tenant name for the most recent fetch so that we
*can* have multiple outstanding requests for different tenants, but
we only accept the most recent one.

Change-Id: Ic49027e137b8c30004d43059db259d10c5443812
This commit is contained in:
James E. Blair 2023-09-15 14:32:28 -07:00
parent 4b347ce91b
commit e429a90722
2 changed files with 85 additions and 19 deletions

View File

@ -1,4 +1,5 @@
// Copyright 2018 Red Hat, Inc
// Copyright 2023 Acme Gating, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
@ -14,23 +15,45 @@
import { fetchConfigErrors } from '../api'
export function fetchConfigErrorsAction (tenant) {
return (dispatch) => {
return fetchConfigErrors(tenant.apiPrefix)
.then(response => {
dispatch({type: 'CONFIGERRORS_FETCH_SUCCESS',
errors: response.data})
})
.catch(error => {
dispatch({type: 'CONFIGERRORS_FETCH_FAIL',
error})
export const CONFIGERRORS_FETCH_REQUEST = 'CONFIGERRORS_FETCH_REQUEST'
export const CONFIGERRORS_FETCH_SUCCESS = 'CONFIGERRORS_FETCH_SUCCESS'
export const CONFIGERRORS_FETCH_FAIL = 'CONFIGERRORS_FETCH_FAIL'
export const CONFIGERRORS_CLEAR = 'CONFIGERRORS_CLEAR'
})
export const requestConfigErrors = (tenant) => ({
type: CONFIGERRORS_FETCH_REQUEST,
tenant: tenant,
})
export const receiveConfigErrors = (tenant, json) => ({
type: CONFIGERRORS_FETCH_SUCCESS,
tenant: tenant,
errors: json,
receivedAt: Date.now()
})
const failedConfigErrors = (tenant, error) => ({
type: CONFIGERRORS_FETCH_FAIL,
tenant: tenant,
error
})
export function fetchConfigErrorsAction (tenant) {
return (dispatch, getState) => {
const state = getState()
if (state.configErrors.isFetching && tenant.name === state.configErrors.tenant) {
return Promise.resolve()
}
dispatch(requestConfigErrors(tenant.name))
return fetchConfigErrors(tenant.apiPrefix)
.then(response => dispatch(receiveConfigErrors(tenant.name, response.data)))
.catch(error => dispatch(failedConfigErrors(tenant.name, error)))
}
}
export function clearConfigErrorsAction () {
return (dispatch) => {
dispatch({type: 'CONFIGERRORS_CLEAR'})
dispatch({type: CONFIGERRORS_CLEAR})
}
}

View File

@ -1,4 +1,5 @@
// Copyright 2018 Red Hat, Inc
// Copyright 2023 Acme Gating, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
@ -12,14 +13,56 @@
// License for the specific language governing permissions and limitations
// under the License.
export default (state = {errors: [], ready: false}, action) => {
import {
CONFIGERRORS_FETCH_FAIL,
CONFIGERRORS_FETCH_REQUEST,
CONFIGERRORS_FETCH_SUCCESS,
CONFIGERRORS_CLEAR
} from '../actions/configErrors'
export default (state = {
errors: [],
isFetching: false,
ready: false,
tenant: '',
}, action) => {
switch (action.type) {
case 'CONFIGERRORS_FETCH_SUCCESS':
return {errors: action.errors, ready: true}
case 'CONFIGERRORS_FETCH_FAIL':
return {errors: [], ready: true}
case 'CONFIGERRORS_CLEAR':
return {errors: [], ready: false}
case CONFIGERRORS_FETCH_REQUEST:
return {
isFetching: true,
ready: false,
tenant: action.tenant,
errors: state.errors,
}
case CONFIGERRORS_FETCH_SUCCESS:
if (action.tenant === state.tenant) {
return {
isFetching: false,
ready: true,
tenant: action.tenant,
errors: action.errors,
}
} else {
return state
}
case CONFIGERRORS_FETCH_FAIL:
if (action.tenant === state.tenant) {
return {
isFetching: false,
ready: false,
tenant: action.tenant,
errors: state.errors,
}
} else {
return state
}
case CONFIGERRORS_CLEAR:
return {
isFetching: false,
ready: false,
tenant: '',
errors: [],
}
default:
return state
}