diff --git a/dashboard/components/Layout.tsx b/dashboard/components/Layout.tsx index a1aacc3ca8995..fd3418c734398 100644 --- a/dashboard/components/Layout.tsx +++ b/dashboard/components/Layout.tsx @@ -145,7 +145,9 @@ function Layout({ children }: { children: React.ReactNode }) { Streaming Dependency Graph Fragment Graph - Back Pressure Rates + + Back Pressure Rates +
Batch diff --git a/dashboard/pages/api/metric.ts b/dashboard/pages/api/metric.ts index fc6c0b022ccb2..eb54621ebaae1 100644 --- a/dashboard/pages/api/metric.ts +++ b/dashboard/pages/api/metric.ts @@ -24,16 +24,16 @@ export interface BackPressuresMetrics { // Get back pressure from meta node -> prometheus export async function getActorBackPressures() { const res: BackPressuresMetrics = await api.get( - "/metrics/actor/back_pressures" + "/metrics/actor/back_pressures", ) return res } export interface BackPressureInfo { - actorId: number, - fragmentId: number, - downstreamFragmentId: number, - value: number, + actorId: number + fragmentId: number + downstreamFragmentId: number + value: number } export const BackPressureInfo = { @@ -41,7 +41,9 @@ export const BackPressureInfo = { return { actorId: isSet(object.actorId) ? Number(object.actorId) : 0, fragmentId: isSet(object.fragmentId) ? Number(object.fragmentId) : 0, - downstreamFragmentId: isSet(object.downstreamFragmentId) ? Number(object.downstreamFragmentId) : 0, + downstreamFragmentId: isSet(object.downstreamFragmentId) + ? Number(object.downstreamFragmentId) + : 0, value: isSet(object.value) ? Number(object.value) : 0, } }, @@ -49,9 +51,13 @@ export const BackPressureInfo = { // Get back pressure from meta node -> compute node export async function getComputeBackPressures() { - const response = await api.get("/metrics/back_pressures"); - let back_pressure_infos: BackPressureInfo[] = response.backPressureInfos.map(BackPressureInfo.fromJSON) - back_pressure_infos = back_pressure_infos.sort((a, b) => a.actorId - b.actorId) + const response = await api.get("/metrics/back_pressures") + let back_pressure_infos: BackPressureInfo[] = response.backPressureInfos.map( + BackPressureInfo.fromJSON, + ) + back_pressure_infos = back_pressure_infos.sort( + (a, b) => a.actorId - b.actorId, + ) return back_pressure_infos } @@ -78,5 +84,5 @@ export function p99(samples: MetricsSample[]) { } function isSet(value: any): boolean { - return value !== null && value !== undefined; + return value !== null && value !== undefined } diff --git a/dashboard/pages/back_pressure_rates.tsx b/dashboard/pages/back_pressure_rates.tsx index 76a2aa8f3cbb7..cd7a3ac0f9f45 100644 --- a/dashboard/pages/back_pressure_rates.tsx +++ b/dashboard/pages/back_pressure_rates.tsx @@ -17,131 +17,140 @@ import Title from "../components/Title" import Head from "next/head" import { - Box, - Table, - TableContainer, - Tbody, - Td, - Th, - Thead, - Tr, + Box, + Table, + TableContainer, + Tbody, + Td, + Th, + Thead, + Tr, } from "@chakra-ui/react" import { Fragment, useEffect, useState } from "react" import { BackPressureInfo, getComputeBackPressures } from "./api/metric" import useErrorToast from "../hook/useErrorToast" -const INTERVAL = 20000; +const INTERVAL = 20000 interface BackPressureRateInfo { - actorId: number, - fragmentId: number, - downstreamFragmentId: number, - backPressureRate: string, + actorId: number + fragmentId: number + downstreamFragmentId: number + backPressureRate: string } function convertToMap(back_pressures: BackPressureInfo[]): Map { - const map = new Map(); - for (const item of back_pressures) { - const key = `${item.actorId}-${item.fragmentId}-${item.downstreamFragmentId}`; - map.set(key, item.value); - } - return map; + const map = new Map() + for (const item of back_pressures) { + const key = `${item.actorId}-${item.fragmentId}-${item.downstreamFragmentId}` + map.set(key, item.value) + } + return map } function convertFromMap(map: Map): BackPressureRateInfo[] { - const result: BackPressureRateInfo[] = []; - map.forEach((value, key) => { - const [actorId, fragmentId, downstreamFragmentId] = key.split('-').map(Number); - const backPressureRateInfo: BackPressureRateInfo = { - actorId, - fragmentId, - downstreamFragmentId, - backPressureRate: value, - }; - result.push(backPressureRateInfo); - }); - return result; + const result: BackPressureRateInfo[] = [] + map.forEach((value, key) => { + const [actorId, fragmentId, downstreamFragmentId] = key + .split("-") + .map(Number) + const backPressureRateInfo: BackPressureRateInfo = { + actorId, + fragmentId, + downstreamFragmentId, + backPressureRate: value, + } + result.push(backPressureRateInfo) + }) + return result } +function calculation( + back_pressure_new: BackPressureInfo[], + back_pressure_old: BackPressureInfo[], +): BackPressureRateInfo[] { + let map_new = convertToMap(back_pressure_new) + let map_old = convertToMap(back_pressure_old) + let result = new Map() + map_new.forEach((value, key) => { + if (map_old.has(key)) { + result.set( + key, + ((value - map_old.get(key)) / (INTERVAL * 1000000000)).toString(), + ) + } else { + result.set(key, "-") + } + }) -function calculation(back_pressure_new: BackPressureInfo[], back_pressure_old: BackPressureInfo[]): BackPressureRateInfo[] { - let map_new = convertToMap(back_pressure_new); - let map_old = convertToMap(back_pressure_old); - let result = new Map(); - map_new.forEach((value, key) => { - if (map_old.has(key)) { - result.set(key, ((value - map_old.get(key)) / (INTERVAL * 1000000000)).toString()); - } else { - result.set(key, "-"); - } - }); - - return convertFromMap(result); + return convertFromMap(result) } export default function back_pressure() { - const [previousBP, setPreviousBP] = useState([]); - const [backPressureRate, setBackPressureRate] = useState([]); - const title = "Back Pressure Rates"; - const toast = useErrorToast() + const [previousBP, setPreviousBP] = useState([]) + const [backPressureRate, setBackPressureRate] = useState< + BackPressureRateInfo[] + >([]) + const title = "Back Pressure Rates" + const toast = useErrorToast() - useEffect(() => { - let localPreviousBP = previousBP; + useEffect(() => { + let localPreviousBP = previousBP - async function fetchData() { - while (true) { - try { - const currentBP = await getComputeBackPressures(); - const backPressureRate = calculation(currentBP, localPreviousBP); - setBackPressureRate(backPressureRate); - localPreviousBP = currentBP; - setPreviousBP(currentBP); - await new Promise((resolve) => setTimeout(resolve, INTERVAL)); - } catch (e: any) { - toast(e, "warning") - break; - } - } + async function fetchData() { + while (true) { + try { + const currentBP = await getComputeBackPressures() + const backPressureRate = calculation(currentBP, localPreviousBP) + setBackPressureRate(backPressureRate) + localPreviousBP = currentBP + setPreviousBP(currentBP) + await new Promise((resolve) => setTimeout(resolve, INTERVAL)) + } catch (e: any) { + toast(e, "warning") + break } + } + } - fetchData(); - return () => { }; - }, [toast]); + fetchData() + return () => {} + }, [toast]) - const table = ( - - {title} - - - - - - - - - - - - {backPressureRate?.map((r) => ( - - - - - - - ))} - -
ActorIdFragmentIdDownStreamFragmentIdBack Pressure Rate
{r.actorId}{r.fragmentId}{r.downstreamFragmentId}{r.backPressureRate}
-
-
- ) + const table = ( + + {title} + + + + + + + + + + + + {backPressureRate?.map((r) => ( + + + + + + + ))} + +
ActorIdFragmentIdDownStreamFragmentIdBack Pressure Rate
{r.actorId}{r.fragmentId}{r.downstreamFragmentId}{r.backPressureRate}
+
+
+ ) - return ( - - - {title} - - {table} - - ) + return ( + + + {title} + + {table} + + ) }