[Fleet] Remove duplicative retries from client-side requests to APIs that depend on EPR (#190722)

## Summary

Relates to https://github.com/elastic/kibana/issues/136617

For APIs that depend on Fleet connecting to Elastic Package Registry,
Fleet already retries the connections to EPR on the server side. This
results in a situation where, when EPR is unreachable, the requests is
retried several times on the server side, and then the request is
retried again on the client-side by react-query. This results in very
long running API requests.

Since the server-side retries generally cover any kind of flakiness
here, disabling the retry logic on the front-end seems sensible. ~I've
also reduced the number of retries on the server side from 5 to 3 to
help fail faster here.~ I walked back the retry change after some test
failures, and I don't think it makes a big enough impact to justify
changing.

## To test

Set `xpack.fleet.registryUrl: 127.0.0.1:8080` with nothing running

## Before

The requests spin for a very long time.


https://github.com/user-attachments/assets/e4fd77ee-b36c-4965-9f71-e5b3e195f75e

## After

The requests stop spinning after a few seconds as the retries won't
loop.


https://github.com/user-attachments/assets/82adc595-1bc4-4269-8501-2eb83525ad15

cc @shahzad31
This commit is contained in:
Kyle Pollich 2024-08-20 10:50:00 -04:00 committed by GitHub
parent cd1d64569a
commit cf3149e983
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 47 additions and 13 deletions

View file

@ -7,12 +7,18 @@
import React, { useCallback, useRef, useEffect, forwardRef } from 'react';
import { css } from '@emotion/react';
import { EuiFlexGrid, EuiFlexItem, EuiSpacer, EuiText, EuiAutoSizer } from '@elastic/eui';
import {
EuiFlexGrid,
EuiFlexItem,
EuiSpacer,
EuiText,
EuiAutoSizer,
EuiSkeletonRectangle,
} from '@elastic/eui';
import { VariableSizeList as List } from 'react-window';
import { FormattedMessage } from '@kbn/i18n-react';
import { WindowScroller } from 'react-virtualized';
import { Loading } from '../../../../components';
import type { IntegrationCardItem } from '../../screens/home';
import { PackageCard } from '../package_card';
@ -66,7 +72,17 @@ export const GridColumn = ({
}
}, []);
if (isLoading) return <Loading />;
if (isLoading) {
return (
<EuiFlexGrid gutterSize="l" columns={3}>
{Array.from({ length: 12 }).map((_, index) => (
<EuiFlexItem key={index} grow={3}>
<EuiSkeletonRectangle height="160px" width="100%" />
</EuiFlexItem>
))}
</EuiFlexGrid>
);
}
if (!list.length) {
return (

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { EuiFacetButton, EuiFacetGroup } from '@elastic/eui';
import { EuiFacetButton, EuiFacetGroup, EuiSpacer } from '@elastic/eui';
import type { IntegrationCategory } from '@kbn/custom-integrations-plugin/common';
import React from 'react';
@ -78,7 +78,11 @@ export function CategoryFacets({
const controls = (
<EuiFacetGroup>
{isLoading ? (
<Loading />
<>
<EuiSpacer size="m" />
<Loading size="l" />
<EuiSpacer size="m" />
</>
) : (
categories.map((category) => {
return (

View file

@ -54,13 +54,16 @@ export function useGetReplacementCustomIntegrationsQuery() {
}
export function useGetCategoriesQuery(query: GetCategoriesRequest['query'] = {}) {
return useQuery<GetCategoriesResponse, RequestError>(['categories', query], () =>
sendRequestForRq<GetCategoriesResponse>({
path: epmRouteService.getCategoriesPath(),
method: 'get',
query,
version: API_VERSIONS.public.v1,
})
return useQuery<GetCategoriesResponse, RequestError>(
['categories', query],
() =>
sendRequestForRq<GetCategoriesResponse>({
path: epmRouteService.getCategoriesPath(),
method: 'get',
query,
version: API_VERSIONS.public.v1,
}),
{ retry: (_, error) => !isRegistryConnectionError(error), refetchOnWindowFocus: false }
);
}
@ -96,6 +99,8 @@ export const useGetPackagesQuery = (
query,
}),
enabled: options?.enabled,
retry: (_, error) => !isRegistryConnectionError(error),
refetchOnWindowFocus: false,
});
};
@ -151,7 +156,12 @@ export const useGetPackageInfoByKeyQuery = (
...(ignoreUnverifiedQueryParam && { ignoreUnverified: ignoreUnverifiedQueryParam }),
},
}),
{ enabled: queryOptions.enabled, refetchOnMount: queryOptions.refetchOnMount }
{
enabled: queryOptions.enabled,
refetchOnMount: queryOptions.refetchOnMount,
retry: (_, error) => !isRegistryConnectionError(error),
refetchOnWindowFocus: false,
}
);
const confirm = async () => {
@ -360,3 +370,7 @@ export function useGetInputsTemplatesQuery(
})
);
}
function isRegistryConnectionError(error: RequestError) {
return error.statusCode === 502;
}