import { FC, PropsWithChildren, useEffect, useState } from "react"; import { useAppDispatch } from "../state/hooks"; import { updateSettings, useSettings } from "../state/settingsSlice"; import { useSuspenseAPIQuery } from "../api/api"; import { WALReplayStatus } from "../api/responseTypes/walreplay"; import { Progress, Stack, Title } from "@mantine/core"; import { useSuspenseQuery } from "@tanstack/react-query"; const ReadinessLoader: FC = () => { const { pathPrefix } = useSettings(); const dispatch = useAppDispatch(); // Query key is incremented every second to retrigger the status fetching. const [queryKey, setQueryKey] = useState(0); // Query readiness status. const { data: ready } = useSuspenseQuery({ queryKey: [`ready-${queryKey}`], retry: false, refetchOnWindowFocus: false, gcTime: 0, queryFn: async ({ signal }: { signal: AbortSignal }) => { try { const res = await fetch(`${pathPrefix}/-/ready`, { cache: "no-store", credentials: "same-origin", signal, }); switch (res.status) { case 200: return true; case 503: return false; default: throw new Error(res.statusText); } } catch (error) { throw new Error("Unexpected error while fetching ready status"); } }, }); // Query WAL replay status. const { data: { data: { min, max, current }, }, } = useSuspenseAPIQuery({ path: `/status/walreplay`, key: `walreplay-${queryKey}`, }); useEffect(() => { if (ready) { dispatch(updateSettings({ ready: ready })); } }, [ready, dispatch]); useEffect(() => { const interval = setInterval(() => setQueryKey((v) => v + 1), 1000); return () => clearInterval(interval); }, []); return ( Starting up... {max > 0 && ( <>

Replaying WAL ({current}/{max})

)}
); }; export const ReadinessWrapper: FC = ({ children }) => { const { ready } = useSettings(); if (ready) { return <>{children}; } return ; }; export default ReadinessWrapper;