From b55566b89b568b4211a467e98cb48a0c4b7ea884 Mon Sep 17 00:00:00 2001 From: Vedant Gupta <49195734+veds-g@users.noreply.github.com> Date: Thu, 3 Aug 2023 10:21:03 +0530 Subject: [PATCH] feat: watermark delay in tooltip (#910) --- ui/package.json | 3 +- .../Graph/partials/CustomEdge/index.test.tsx | 88 +++++++++++++++++-- .../Graph/partials/CustomEdge/index.tsx | 50 +++++++++-- .../Graph/partials/Spec/index.test.tsx | 2 +- ui/src/types/declarations/pipeline.d.ts | 1 + .../utils/fetcherHooks/pipelineViewFetch.ts | 1 + ui/yarn.lock | 5 ++ 7 files changed, 135 insertions(+), 15 deletions(-) diff --git a/ui/package.json b/ui/package.json index 3560e1a88d..980715d352 100644 --- a/ui/package.json +++ b/ui/package.json @@ -30,6 +30,7 @@ "d3-scale": "^4.0.2", "d3-selection": "^3.0.0", "dagre": "^0.8.5", + "moment": "^2.29.4", "msw": "^0.47.4", "react": "^18.0.0", "react-dom": "^18.0.0", @@ -77,7 +78,7 @@ }, "jest": { "transformIgnorePatterns": [ - "/node_modules/(?!d3|d3-array|internmap|delaunator|robust-predicates|reactflow|react-toastify)" + "/node_modules/(?!d3|d3-array|internmap|delaunator|robust-predicates|reactflow|react-toastify|moment)" ] } } diff --git a/ui/src/components/pages/Pipeline/partials/Graph/partials/CustomEdge/index.test.tsx b/ui/src/components/pages/Pipeline/partials/Graph/partials/CustomEdge/index.test.tsx index 45c8bb47e0..a584a5c552 100644 --- a/ui/src/components/pages/Pipeline/partials/Graph/partials/CustomEdge/index.test.tsx +++ b/ui/src/components/pages/Pipeline/partials/Graph/partials/CustomEdge/index.test.tsx @@ -17,7 +17,9 @@ describe("Graph screen test", () => { targetPosition={Position.Left} data={{ backpressureLabel: "0", - edgeWatermark: null, + edgeWatermark: { + isWaterMarkEnabled: true, + }, }} source={"first"} target={"second"} @@ -28,7 +30,7 @@ describe("Graph screen test", () => { expect(screen.getByTestId(`first-second`)).toBeInTheDocument() ); }); - it("Straight edge but full", async () => { + it("Straight edge but full with delay in mo", async () => { render( { backpressureLabel: "0", edgeWatermark: { isWaterMarkEnabled: true, - watermarks: [1690792996319], + watermarks: [Date.now() - 2678400000], }, }} source={"first"} @@ -56,7 +58,7 @@ describe("Graph screen test", () => { expect(screen.getByTestId(`first-second`)).toBeInTheDocument() ); }); - it("Edge branches into two", async () => { + it("Edge branches with delays in ms, sec, min, hr, d", async () => { render( { data={{ isFull: "false", backpressureLabel: "0", - edgeWatermark: null, + edgeWatermark: { + isWaterMarkEnabled: true, + watermarks: [Date.now() - 1], + }, }} source={"first"} target={"second"} @@ -80,17 +85,77 @@ describe("Graph screen test", () => { sourceX={240} sourceY={36} targetX={334} - targetY={32} + targetY={38} sourcePosition={Position.Right} targetPosition={Position.Left} data={{ isFull: "false", backpressureLabel: "0", - edgeWatermark: null, + edgeWatermark: { + isWaterMarkEnabled: true, + watermarks: [Date.now() - 1000], + }, }} source={"first"} target={"third"} /> + + + ); await waitFor(() => @@ -99,5 +164,14 @@ describe("Graph screen test", () => { await waitFor(() => expect(screen.getByTestId(`first-third`)).toBeInTheDocument() ); + await waitFor(() => + expect(screen.getByTestId(`first-fourth`)).toBeInTheDocument() + ); + await waitFor(() => + expect(screen.getByTestId(`first-fifth`)).toBeInTheDocument() + ); + await waitFor(() => + expect(screen.getByTestId(`first-sixth`)).toBeInTheDocument() + ); }); }); diff --git a/ui/src/components/pages/Pipeline/partials/Graph/partials/CustomEdge/index.tsx b/ui/src/components/pages/Pipeline/partials/Graph/partials/CustomEdge/index.tsx index ea0c2a6be5..461f1b557e 100644 --- a/ui/src/components/pages/Pipeline/partials/Graph/partials/CustomEdge/index.tsx +++ b/ui/src/components/pages/Pipeline/partials/Graph/partials/CustomEdge/index.tsx @@ -1,6 +1,7 @@ import { FC, memo } from "react"; import { Tooltip } from "@mui/material"; import { EdgeProps, EdgeLabelRenderer, getSmoothStepPath } from "reactflow"; +import { duration } from "moment"; import "reactflow/dist/style.css"; import "./style.css"; @@ -50,6 +51,46 @@ const CustomEdge: FC = ({ labelY = targetY + 2; } } + const getMinWM = () => { + if (data?.edgeWatermark?.watermarks) { + return Math.min.apply(null, data?.edgeWatermark?.watermarks); + } else { + return -1; + } + }; + + const getDelay = () => { + const str = " behind now"; + const fetchWMTime = data?.edgeWatermark?.WMFetchTime; + const minWM = getMinWM(); + const startTime = minWM === -1 ? 0 : minWM; + const endTime = fetchWMTime || Date.now(); + const diff = duration(endTime - startTime); + + const years = diff.years(); + const months = diff.months(); + const days = diff.days(); + const hours = diff.hours(); + const minutes = diff.minutes(); + const seconds = diff.seconds(); + const milliseconds = diff.milliseconds(); + + if (years > 0) { + return `${years}yr ${months}mo` + str; + } else if (months > 0) { + return `${months}mo ${days}d` + str; + } else if (days > 0) { + return `${days}d ${hours}hr` + str; + } else if (hours > 0) { + return `${hours}hr ${minutes}min` + str; + } else if (minutes > 0) { + return `${minutes}min ${seconds}sec` + str; + } else if (seconds > 0) { + return `${seconds}sec ${milliseconds}ms` + str; + } else { + return `${milliseconds}ms` + str; + } + }; return ( <> @@ -74,18 +115,15 @@ const CustomEdge: FC = ({ title={
Watermark
-
- {new Date( - Math.min.apply(null, data?.edgeWatermark?.watermarks) - ).toISOString()} -
+
{new Date(getMinWM()).toISOString()}
+
{getDelay()}
} arrow placement={"top"} >
- {Math.min.apply(null, data?.edgeWatermark?.watermarks)} + {getMinWM()}
)} diff --git a/ui/src/components/pages/Pipeline/partials/Graph/partials/Spec/index.test.tsx b/ui/src/components/pages/Pipeline/partials/Graph/partials/Spec/index.test.tsx index 842ed4d7e2..1988758def 100644 --- a/ui/src/components/pages/Pipeline/partials/Graph/partials/Spec/index.test.tsx +++ b/ui/src/components/pages/Pipeline/partials/Graph/partials/Spec/index.test.tsx @@ -1,5 +1,5 @@ import Spec from "./index"; -import { fireEvent, render, screen } from "@testing-library/react"; +import { render, screen } from "@testing-library/react"; import { BrowserRouter } from "react-router-dom"; describe("Spec", () => { diff --git a/ui/src/types/declarations/pipeline.d.ts b/ui/src/types/declarations/pipeline.d.ts index 3efcc4d8f4..f879ba65c8 100644 --- a/ui/src/types/declarations/pipeline.d.ts +++ b/ui/src/types/declarations/pipeline.d.ts @@ -11,6 +11,7 @@ export interface VertexMetrics { export interface EdgeWatermark { watermarks: any[]; isWaterMarkEnabled: boolean; + WMFetchTime: number; } export interface BufferInfo { diff --git a/ui/src/utils/fetcherHooks/pipelineViewFetch.ts b/ui/src/utils/fetcherHooks/pipelineViewFetch.ts index f921bc0955..b0192dd5d8 100644 --- a/ui/src/utils/fetcherHooks/pipelineViewFetch.ts +++ b/ui/src/utils/fetcherHooks/pipelineViewFetch.ts @@ -268,6 +268,7 @@ export const usePipelineViewFetch = ( const edgeWatermark = {} as EdgeWatermark; edgeWatermark.isWaterMarkEnabled = edge["isWatermarkEnabled"]; edgeWatermark.watermarks = edge["watermarks"]; + edgeWatermark.WMFetchTime = Date.now(); edgeToWatermarkMap.set(edge.edge, edgeWatermark); }); }), diff --git a/ui/yarn.lock b/ui/yarn.lock index 5085b04e25..a9599507b2 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -7859,6 +7859,11 @@ mkdirp@~0.5.1: dependencies: minimist "^1.2.6" +moment@^2.29.4: + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"