feat: improve getHealth logic (#2537)
* create get health custom hook * refactor getHealth to use useQuery get * fix: getHealth in App.tsx * [autofix.ci] apply automated fixes * refactor: update API endpoint in useGetHealthQuery * chore: use new get_helth body * [autofix.ci] apply automated fixes * update interfaces names * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Cristhian Zanforlin Lousa <72977554+Cristhianzl@users.noreply.github.com>
This commit is contained in:
parent
71e3ed92d8
commit
6160f70011
4 changed files with 69 additions and 69 deletions
|
|
@ -1,4 +1,3 @@
|
|||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { ErrorBoundary } from "react-error-boundary";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
|
@ -13,7 +12,8 @@ import {
|
|||
FETCH_ERROR_MESSAGE,
|
||||
} from "./constants/constants";
|
||||
import { AuthContext } from "./contexts/authContext";
|
||||
import { autoLogin, getGlobalVariables, getHealth } from "./controllers/API";
|
||||
import { autoLogin } from "./controllers/API";
|
||||
import { useGetHealthQuery } from "./controllers/API/queries/health";
|
||||
import { useGetVersionQuery } from "./controllers/API/queries/version";
|
||||
import { setupAxiosDefaults } from "./controllers/API/utils";
|
||||
import useTrackLastVisitedPath from "./hooks/use-track-last-visited-path";
|
||||
|
|
@ -25,21 +25,22 @@ import useFlowsManagerStore from "./stores/flowsManagerStore";
|
|||
import { useFolderStore } from "./stores/foldersStore";
|
||||
|
||||
export default function App() {
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
useTrackLastVisitedPath();
|
||||
const [fetchError, setFetchError] = useState(false);
|
||||
const isLoading = useFlowsManagerStore((state) => state.isLoading);
|
||||
const { isAuthenticated, login, setUserData, setAutoLogin, getUser } =
|
||||
useContext(AuthContext);
|
||||
const setLoading = useAlertStore((state) => state.setLoading);
|
||||
const refreshStars = useDarkStore((state) => state.refreshStars);
|
||||
const navigate = useNavigate();
|
||||
const dark = useDarkStore((state) => state.dark);
|
||||
|
||||
const isLoadingFolders = useFolderStore((state) => state.isLoadingFolders);
|
||||
|
||||
const [isLoadingHealth, setIsLoadingHealth] = useState(false);
|
||||
const {
|
||||
data: healthData,
|
||||
isFetching: fetchingHealth,
|
||||
isError: isErrorHealth,
|
||||
refetch,
|
||||
} = useGetHealthQuery();
|
||||
useEffect(() => {
|
||||
if (!dark) {
|
||||
document.getElementById("body")!.classList.remove("dark");
|
||||
|
|
@ -102,49 +103,6 @@ export default function App() {
|
|||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
checkApplicationHealth();
|
||||
// Timer to call getHealth every 5 seconds
|
||||
const timer = setInterval(() => {
|
||||
getHealth()
|
||||
.then(() => {
|
||||
onHealthCheck();
|
||||
})
|
||||
.catch(() => {
|
||||
setFetchError(true);
|
||||
});
|
||||
}, 20000); // 20 seconds
|
||||
|
||||
// Clean up the timer on component unmount
|
||||
return () => {
|
||||
clearInterval(timer);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const checkApplicationHealth = () => {
|
||||
setIsLoadingHealth(true);
|
||||
getHealth()
|
||||
.then(() => {
|
||||
onHealthCheck();
|
||||
})
|
||||
.catch(() => {
|
||||
setFetchError(true);
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
setIsLoadingHealth(false);
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
const onHealthCheck = () => {
|
||||
setFetchError(false);
|
||||
//This condition is necessary to avoid infinite loop on starter page when the application is not healthy
|
||||
if (isLoading === true && window.location.pathname === "/") {
|
||||
navigate("/all");
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
const isLoadingApplication = isLoading || isLoadingFolders;
|
||||
|
||||
return (
|
||||
|
|
@ -161,11 +119,16 @@ export default function App() {
|
|||
<FetchErrorComponent
|
||||
description={FETCH_ERROR_DESCRIPION}
|
||||
message={FETCH_ERROR_MESSAGE}
|
||||
openModal={fetchError}
|
||||
openModal={
|
||||
isErrorHealth ||
|
||||
(healthData &&
|
||||
Object.values(healthData).some((value) => value !== "ok"))
|
||||
}
|
||||
setRetry={() => {
|
||||
checkApplicationHealth();
|
||||
console.log("retrying");
|
||||
refetch();
|
||||
}}
|
||||
isLoadingHealth={isLoadingHealth}
|
||||
isLoadingHealth={fetchingHealth}
|
||||
></FetchErrorComponent>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -319,22 +319,6 @@ export async function getVersion() {
|
|||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the health status of the API.
|
||||
*
|
||||
* @returns {Promise<AxiosResponse<any>>} A promise that resolves to an AxiosResponse containing the health status.
|
||||
*/
|
||||
export async function getHealth() {
|
||||
return await api.get("/health").catch((e) => {
|
||||
if (e.code === "ECONNABORTED") {
|
||||
console.log("request cancelled");
|
||||
} else {
|
||||
// raise error to be caught by the caller
|
||||
throw e;
|
||||
}
|
||||
}); // Health is the only endpoint that doesn't require /api/v1
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the build status of a flow.
|
||||
* @param {string} flowId - The ID of the flow to fetch the build status for.
|
||||
|
|
|
|||
1
src/frontend/src/controllers/API/queries/health/index.ts
Normal file
1
src/frontend/src/controllers/API/queries/health/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "./use-get-health";
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
import { keepPreviousData } from "@tanstack/react-query";
|
||||
import { useQueryFunctionType } from "../../../../types/api";
|
||||
import { api } from "../../api";
|
||||
import { UseRequestProcessor } from "../../services/request-processor";
|
||||
|
||||
interface getHealthResponse {
|
||||
status: string;
|
||||
chat: string;
|
||||
db: string;
|
||||
folder: string;
|
||||
variables: string;
|
||||
}
|
||||
|
||||
export const useGetHealthQuery: useQueryFunctionType<
|
||||
undefined,
|
||||
getHealthResponse
|
||||
> = (_, onFetch) => {
|
||||
const { query } = UseRequestProcessor();
|
||||
|
||||
const responseFn = (data: getHealthResponse) => {
|
||||
if (!onFetch) return data;
|
||||
if (typeof onFetch === "function") return onFetch(data);
|
||||
switch (onFetch) {
|
||||
default:
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetches the health status of the API.
|
||||
*
|
||||
* @returns {Promise<AxiosResponse<TransactionsResponse>>} A promise that resolves to an AxiosResponse containing the health status.
|
||||
*/
|
||||
async function getHealthFn() {
|
||||
return await api.get("/health_check");
|
||||
// Health is the only endpoint that doesn't require /api/v1
|
||||
}
|
||||
|
||||
const queryResult = query(
|
||||
["useGetHealthQuery"],
|
||||
async () => {
|
||||
const result = await getHealthFn();
|
||||
return responseFn(result.data);
|
||||
},
|
||||
{
|
||||
placeholderData: keepPreviousData,
|
||||
refetchInterval: 20000,
|
||||
},
|
||||
);
|
||||
|
||||
return queryResult;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue