From ab5ee7784218b02e7c5b6aa6bc7bd2494369cfd1 Mon Sep 17 00:00:00 2001 From: Mariusz Klochowicz Date: Mon, 15 Nov 2021 14:14:59 +1030 Subject: [PATCH] Monitor for taker's backend presence in the UI It's important to have this in the meantime, otherwise taker will get shutdown when maker goes offline and we will not notice it. --- taker-frontend/src/App.tsx | 2 + .../src/components/BackendMonitor.tsx | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 taker-frontend/src/components/BackendMonitor.tsx diff --git a/taker-frontend/src/App.tsx b/taker-frontend/src/App.tsx index 466864c..168e057 100644 --- a/taker-frontend/src/App.tsx +++ b/taker-frontend/src/App.tsx @@ -5,6 +5,7 @@ import { useAsync } from "react-async"; import { Route, Switch } from "react-router-dom"; import { useEventSource } from "react-sse-hooks"; import useWebSocket from "react-use-websocket"; +import { useBackendMonitor } from "./components/BackendMonitor"; import History from "./components/History"; import Nav from "./components/NavBar"; import Trade from "./components/Trade"; @@ -43,6 +44,7 @@ async function postCfdOrderRequest(payload: CfdOrderRequestPayload) { export const App = () => { const toast = useToast(); + useBackendMonitor(toast, 5000); // 5s timeout const { lastMessage, diff --git a/taker-frontend/src/components/BackendMonitor.tsx b/taker-frontend/src/components/BackendMonitor.tsx new file mode 100644 index 0000000..f899a1d --- /dev/null +++ b/taker-frontend/src/components/BackendMonitor.tsx @@ -0,0 +1,50 @@ +import { useEffect, useRef } from "react"; + +async function fetchWithTimeout(resource: any, timeout: number) { + const controller = new AbortController(); + const id = setTimeout(() => controller.abort(), timeout); + const response = await fetch(resource, { + signal: controller.signal, + }); + clearTimeout(id); + return response; +} + +// Check for backend's presence by sending a request to '/alive' endpoint. +// When the backend's not there, the request is likely to timeout, triggering a +// persistent toast notification that goes away when the daemon is back online. +export function useBackendMonitor(toast: any, timeout_ms: number): void { + const toastIdRef = useRef(); + + const checkForBackend: () => void = async () => { + try { + const res = await fetchWithTimeout("/alive", timeout_ms); + // In case we get a response, but it's not what we expected + if (res.status.toString().startsWith("2")) { + if (toastIdRef.current) { + toast.close(toastIdRef.current); + } + } else { + throw new Error(res.statusText); + } + } catch (e) { + if (!toastIdRef.current) { + toastIdRef.current = toast({ + title: "Connection Error", + description: "Daemon process is not running", + status: "error", + position: "top", + duration: timeout_ms * 100000, // we don't want this to be closed + isClosable: false, + }); + } + } + }; + + useEffect(() => { + const interval = setInterval(() => checkForBackend(), timeout_ms); + return () => { + clearInterval(interval); + }; + }); +}