diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx
index ecf5cba07..6271458b4 100644
--- a/src/frontend/src/App.tsx
+++ b/src/frontend/src/App.tsx
@@ -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() {
value !== "ok"))
+ }
setRetry={() => {
- checkApplicationHealth();
+ console.log("retrying");
+ refetch();
}}
- isLoadingHealth={isLoadingHealth}
+ isLoadingHealth={fetchingHealth}
>
}
diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts
index ebb5d1247..e586e2803 100644
--- a/src/frontend/src/controllers/API/index.ts
+++ b/src/frontend/src/controllers/API/index.ts
@@ -319,22 +319,6 @@ export async function getVersion() {
return response.data;
}
-/**
- * Fetches the health status of the API.
- *
- * @returns {Promise>} 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.
diff --git a/src/frontend/src/controllers/API/queries/health/index.ts b/src/frontend/src/controllers/API/queries/health/index.ts
new file mode 100644
index 000000000..0a1e53bf4
--- /dev/null
+++ b/src/frontend/src/controllers/API/queries/health/index.ts
@@ -0,0 +1 @@
+export * from "./use-get-health";
diff --git a/src/frontend/src/controllers/API/queries/health/use-get-health.ts b/src/frontend/src/controllers/API/queries/health/use-get-health.ts
new file mode 100644
index 000000000..bf9d392e4
--- /dev/null
+++ b/src/frontend/src/controllers/API/queries/health/use-get-health.ts
@@ -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>} 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;
+};