🐛 Fix issues with URL being too long when pinging many apps (#1264)

This commit is contained in:
Thomas Camlong
2023-08-12 21:57:20 +02:00
committed by GitHub
parent abb52b093a
commit c8f39033dd
3 changed files with 59 additions and 52 deletions

View File

@@ -16,16 +16,15 @@ export const AppPing = ({ app }: AppPingProps) => {
const { config } = useConfigContext(); const { config } = useConfigContext();
const { data, isFetching, isError, error, isActive } = usePing(app); const { data, isFetching, isError, error, isActive } = usePing(app);
const tooltipLabel = useTooltipLabel({isFetching, isError, data, errorMessage: error?.message}) const tooltipLabel = useTooltipLabel({ isFetching, isError, data, errorMessage: error?.message });
const isOnline = isError ? false : data?.state === 'online'; const isOnline = isError ? false : data?.state === 'online';
const pulse = usePingPulse({isOnline}); const pulse = usePingPulse({ isOnline });
if (!isActive) return null; if (!isActive) return null;
const replaceDotWithIcon = const replaceDotWithIcon =
config?.settings.customization.accessibility?.replacePingDotsWithIcons ?? false; config?.settings.customization.accessibility?.replacePingDotsWithIcons ?? false;
return ( return (
<motion.div <motion.div
style={{ style={{
@@ -37,11 +36,7 @@ export const AppPing = ({ app }: AppPingProps) => {
animate={pulse.animate} animate={pulse.animate}
transition={pulse.transition} transition={pulse.transition}
> >
<Tooltip <Tooltip withinPortal radius="lg" label={tooltipLabel}>
withinPortal
radius="lg"
label={tooltipLabel}
>
{replaceDotWithIcon ? ( {replaceDotWithIcon ? (
<Box> <Box>
<AccessibleIndicatorPing isFetching={isFetching} isOnline={isOnline} /> <AccessibleIndicatorPing isFetching={isFetching} isOnline={isOnline} />
@@ -61,12 +56,9 @@ export const AppPing = ({ app }: AppPingProps) => {
type AccessibleIndicatorPingProps = { type AccessibleIndicatorPingProps = {
isOnline: boolean; isOnline: boolean;
isFetching: boolean; isFetching: boolean;
} };
const AccessibleIndicatorPing = ({ const AccessibleIndicatorPing = ({ isFetching, isOnline }: AccessibleIndicatorPingProps) => {
isFetching,
isOnline,
}: AccessibleIndicatorPingProps) => {
if (isOnline) { if (isOnline) {
return <IconCheck color="green" />; return <IconCheck color="green" />;
} }
@@ -90,54 +82,68 @@ type TooltipLabelProps = {
isError: boolean; isError: boolean;
data: RouterOutputs['app']['ping'] | undefined; data: RouterOutputs['app']['ping'] | undefined;
errorMessage: string | undefined; errorMessage: string | undefined;
} };
const useTooltipLabel = ({isFetching, isError, data, errorMessage}: TooltipLabelProps) => { const useTooltipLabel = ({ isFetching, isError, data, errorMessage }: TooltipLabelProps) => {
const { t } = useTranslation('modules/ping'); const { t } = useTranslation('modules/ping');
if (isFetching) return t('states.loading'); if (isFetching) return t('states.loading');
if (isError) return errorMessage; if (isError) return errorMessage;
if (data?.state === 'online') return t('states.online', { response: data?.status ?? 'N/A' }); if (data?.state === 'online') return t('states.online', { response: data?.status ?? 'N/A' });
return `${data?.statusText}: ${data?.status} (denied)`; return `${data?.statusText}: ${data?.status} (denied)`;
} };
const usePing = (app: AppType) => { const usePing = (app: AppType) => {
const { config, name } = useConfigContext(); const { config, name } = useConfigContext();
const isActive = (config?.settings.customization.layout.enabledPing && app.network.enabledStatusChecker) ?? const isActive =
false; (config?.settings.customization.layout.enabledPing && app.network.enabledStatusChecker) ??
false;
const queryResult = api.app.ping.useQuery({ const queryResult = api.app.ping.useQuery(
id: app.id, {
configName: name ?? '' id: app.id,
}, { configName: name ?? '',
retry: false,
enabled: isActive,
select: (data) => {
const isOk = isStatusOk(app, data.status);
if (isOk)
Consola.info(`Ping of app "${app.name}" (${app.url}) returned ${data.status} (Accepted)`);
else
Consola.warn(`Ping of app "${app.name}" (${app.url}) returned ${data.status} (Refused)`);
return {
status: data.status,
state: isOk ? ('online' as const) : ('down' as const),
statusText: data.statusText,
};
}, },
}); {
retry: false,
refetchOnWindowFocus: false,
retryDelay(failureCount, error) {
// TODO: Add logic to retry on timeout
return 3000;
},
// 5 minutes of cache
cacheTime: 1000 * 60 * 5,
staleTime: 1000 * 60 * 5,
retryOnMount: true,
enabled: isActive,
select: (data) => {
const isOk = isStatusOk(app, data.status);
if (isOk)
Consola.info(`Ping of app "${app.name}" (${app.url}) returned ${data.status} (Accepted)`);
else
Consola.warn(`Ping of app "${app.name}" (${app.url}) returned ${data.status} (Refused)`);
return {
status: data.status,
state: isOk ? ('online' as const) : ('down' as const),
statusText: data.statusText,
};
},
}
);
return { return {
...queryResult, ...queryResult,
isActive isActive,
} };
} };
type PingPulse = { type PingPulse = {
animate?: TargetAndTransition; animate?: TargetAndTransition;
transition?: Transition; transition?: Transition;
} };
const usePingPulse = ({isOnline}: {isOnline: boolean}): PingPulse => { const usePingPulse = ({ isOnline }: { isOnline: boolean }): PingPulse => {
const { config } = useConfigContext(); const { config } = useConfigContext();
const disablePulse = config?.settings.customization.accessibility?.disablePingPulse ?? false; const disablePulse = config?.settings.customization.accessibility?.disablePingPulse ?? false;
@@ -147,12 +153,12 @@ const usePingPulse = ({isOnline}: {isOnline: boolean}): PingPulse => {
return { return {
animate: { animate: {
scale: isOnline ? [1, 0.7, 1] : 1 scale: isOnline ? [1, 0.7, 1] : 1,
}, },
transition: { transition: {
repeat: Infinity, repeat: Infinity,
duration: 2.5, duration: 2.5,
ease: 'easeInOut', ease: 'easeInOut',
} },
} };
} };

View File

@@ -23,11 +23,11 @@ export const appRouter = createTRPCRouter({
throw new TRPCError({ throw new TRPCError({
code: 'NOT_FOUND', code: 'NOT_FOUND',
cause: input, cause: input,
message: `App ${input} was not found`, message: `App ${input.id} was not found`,
}); });
} }
const res = await axios const res = await axios
.get(app.url, { httpsAgent: agent, timeout: 2000 }) .get(app.url, { httpsAgent: agent, timeout: 10000 })
.then((response) => ({ .then((response) => ({
status: response.status, status: response.status,
statusText: response.statusText, statusText: response.statusText,

View File

@@ -31,6 +31,7 @@ const getTrpcConfiguration = () => ({
}), }),
httpBatchLink({ httpBatchLink({
url: `${getBaseUrl()}/api/trpc`, url: `${getBaseUrl()}/api/trpc`,
maxURLLength: 2000,
}), }),
], ],
}); });