Jelajahi Sumber

super simple event polling (#3133)

Feroze Mohideen 2 tahun lalu
induk
melakukan
080c5e9069

+ 57 - 42
dashboard/src/main/home/app-dashboard/expanded-app/activity-feed/ActivityFeed.tsx

@@ -5,7 +5,6 @@ import api from "shared/api";
 import { Context } from "shared/Context";
 
 import Text from "components/porter/Text";
-import Container from "components/porter/Container";
 
 import EventCard from "./events/EventCard";
 import Loading from "components/Loading";
@@ -14,7 +13,7 @@ import Fieldset from "components/porter/Fieldset";
 
 import { feedDate } from "shared/string_utils";
 import Pagination from "components/porter/Pagination";
-import { PorterAppEvent, PorterAppEventType } from "shared/types";
+import _ from "lodash";
 import Button from "components/porter/Button";
 
 type Props = {
@@ -23,6 +22,8 @@ type Props = {
   appData: string;
 };
 
+const EVENT_REFRESH_INTERVAL = 5000;
+
 const ActivityFeed: React.FC<Props> = ({ chart, stackName, appData }) => {
   const { currentProject, currentCluster } = useContext(Context);
 
@@ -35,54 +36,68 @@ const ActivityFeed: React.FC<Props> = ({ chart, stackName, appData }) => {
   const [isPorterAgentInstalling, setIsPorterAgentInstalling] = useState(false);
 
   useEffect(() => {
+    const checkForAgent = async () => {
+      const project_id = currentProject?.id;
+      const cluster_id = currentCluster?.id;
+      if (project_id == null || cluster_id == null) {
+        setError(true);
+        return;
+      }
+      try {
+        const res = await api.detectPorterAgent("<token>", {}, { project_id, cluster_id });
+        const hasAgent = res.data?.version === "v3";
+        setHasPorterAgent(hasAgent);
+      } catch (err) {
+        if (err.response?.status === 404) {
+          setHasPorterAgent(false);
+        }
+      }
+    };
+
     checkForAgent();
-  }, []);
 
-  const checkForAgent = () => {
-    const project_id = currentProject?.id;
-    const cluster_id = currentCluster?.id;
+    if (hasPorterAgent) {
+      setLoading(true);
 
-    api
-      .detectPorterAgent("<token>", {}, { project_id, cluster_id })
-      .then((res: any) => {
-        if (res.data?.version != "v3") {
-          setHasPorterAgent(false);
-        } else {
-          setHasPorterAgent(true);
+      const getEvents = async () => {
+        if (!currentProject || !currentCluster) {
+          setError(true);
+          return;
         }
-      })
-      .catch((err) => {
-        if (err.response?.status === 404) {
-          setHasPorterAgent(false);
+        try {
+          const res = await api.getFeedEvents(
+            "<token>",
+            {},
+            {
+              cluster_id: currentCluster.id,
+              project_id: currentProject.id,
+              stack_name: stackName,
+              page,
+            }
+          );
+          if (!_.isEqual(events, res.data.events) || res.data.num_pages !== numPages) {
+            setNumPages(res.data.num_pages);
+            setEvents(res.data.events);
+          }
+          setError(false);
+        } catch (err) {
+          setError(err);
+        } finally {
+          setLoading(false);
         }
-      });
-  };
+      };
 
-  const getEvents = async () => {
-    setLoading(true);
-    try {
-      const res = await api.getFeedEvents(
-        "<token>",
-        {},
-        {
-          cluster_id: currentCluster.id,
-          project_id: currentProject.id,
-          stack_name: stackName,
-          page,
-        }
-      );
-      setNumPages(res.data.num_pages);
-      setEvents(res.data.events);
-      setLoading(false);
-    } catch (err) {
-      setError(err);
-      setLoading(false);
+      getEvents();
+
+      const intervalId = setInterval(getEvents, EVENT_REFRESH_INTERVAL);
+
+      return () => {
+        // Clean up the interval on component unmount
+        clearInterval(intervalId);
+      };
     }
-  };
+  }, [currentProject, currentCluster, page, hasPorterAgent, events, numPages]);
 
-  useEffect(() => {
-    getEvents();
-  }, [page]);
 
   const installAgent = async () => {
     const project_id = currentProject?.id;

+ 10 - 7
dashboard/src/main/home/app-dashboard/expanded-app/activity-feed/events/PreDeployEventCard.tsx

@@ -102,16 +102,19 @@ const PreDeployEventCard: React.FC<Props> = ({ event, appData }) => {
           <Icon height="16px" src={getStatusIcon(event.status)} />
           <Spacer inline width="10px" />
           {renderStatusText(event)}
-          <Spacer inline x={1} />
-          <Wrapper>
-            <Link hasunderline onClick={getPredeployLogs}>
-              View logs
-            </Link>
-          </Wrapper>
+          {(event.status === "SUCCESS" || event.status === "FAILED") &&
+            <>
+              <Spacer inline x={1} />
+              <Wrapper>
+                <Link hasunderline onClick={getPredeployLogs}>
+                  View logs
+                </Link>
+              </Wrapper>
+            </>
+          }
           {event.status === "FAILED" && (
             <>
               <Spacer inline x={1} />
-
               <Link hasunderline onClick={() => triggerWorkflow(appData)}>
                 <Container row>
                   <Icon height="10px" src={refresh} />

+ 1 - 2
dashboard/src/shared/api.tsx

@@ -256,8 +256,7 @@ const getFeedEvents = baseApi<
   }
 >("GET", (pathParams) => {
   let { project_id, cluster_id, stack_name, page } = pathParams;
-  return `/api/projects/${project_id}/clusters/${cluster_id}/stacks/${stack_name}/events?page=${page || 1
-    }`;
+  return `/api/projects/${project_id}/clusters/${cluster_id}/stacks/${stack_name}/events?page=${page || 1}`;
 });
 
 const createEnvironment = baseApi<