From ae93d16d2f411bdbdfa51ebedd5f6b4be18d3912 Mon Sep 17 00:00:00 2001 From: Maciej Bodek Date: Thu, 12 Dec 2024 22:27:26 +0100 Subject: [PATCH] Refactor time filters to use eventBus and rely on FROM/TO --- .../web-console/src/modules/EventBus/types.ts | 1 + .../src/scenes/Editor/Metrics/graph.tsx | 8 +-- .../src/scenes/Editor/Metrics/index.tsx | 39 ++++------- .../src/scenes/Editor/Metrics/metric.tsx | 69 ++++++++++++------- .../scenes/Editor/Metrics/useGraphOptions.ts | 6 +- .../src/scenes/Editor/Metrics/utils.ts | 5 ++ 6 files changed, 73 insertions(+), 55 deletions(-) diff --git a/packages/web-console/src/modules/EventBus/types.ts b/packages/web-console/src/modules/EventBus/types.ts index c05e7bd1a..598f890c7 100644 --- a/packages/web-console/src/modules/EventBus/types.ts +++ b/packages/web-console/src/modules/EventBus/types.ts @@ -19,4 +19,5 @@ export enum EventType { REACT_READY = "react.ready", TAB_FOCUS = "tab.focus", TAB_BLUR = "tab.blur", + METRICS_REFRESH_DATA = "metrics.refresh.data", } diff --git a/packages/web-console/src/scenes/Editor/Metrics/graph.tsx b/packages/web-console/src/scenes/Editor/Metrics/graph.tsx index 5ae5579ea..0a7b60f3c 100644 --- a/packages/web-console/src/scenes/Editor/Metrics/graph.tsx +++ b/packages/web-console/src/scenes/Editor/Metrics/graph.tsx @@ -92,8 +92,8 @@ const LabelValue = styled.span` type Props = { dateFrom: Date - dateNow: Date - lastRefresh?: number + dateTo: Date + lastRefresh?: Date tableId?: number tableName?: string beforeLabel?: React.ReactNode @@ -109,7 +109,7 @@ type Props = { export const Graph = ({ dateFrom, - dateNow, + dateTo, lastRefresh, tableId, tableName, @@ -139,7 +139,7 @@ export const Graph = ({ const graphOptions = useGraphOptions({ data, dateFrom, - dateNow, + dateTo, colors, duration, timeRef, diff --git a/packages/web-console/src/scenes/Editor/Metrics/index.tsx b/packages/web-console/src/scenes/Editor/Metrics/index.tsx index 8916e4516..c460d681b 100644 --- a/packages/web-console/src/scenes/Editor/Metrics/index.tsx +++ b/packages/web-console/src/scenes/Editor/Metrics/index.tsx @@ -14,6 +14,7 @@ import { FetchMode, SampleBy, durationInMinutes, + MetricsRefreshPayload, } from "./utils" import { GridAlt, @@ -121,19 +122,11 @@ export const Metrics = () => { const [metricViewMode, setMetricViewMode] = useState( MetricViewMode.GRID, ) - const [dateFrom, setDateFrom] = useState( - subMinutes( - new Date(), - durationInMinutes[metricDuration || MetricDuration.ONE_HOUR], - ), - ) - const [dateNow, setDateNow] = useState(new Date()) const [refreshRate, setRefreshRate] = useState() const [sampleBy, setSampleBy] = useState() const [dialogOpen, setDialogOpen] = useState(false) const [metrics, setMetrics] = useState([]) const telemetryConfig = useSelector(selectors.telemetry.getConfig) - const [lastRefresh, setLastRefresh] = useState() const [fetchMode, setFetchMode] = useState(FetchMode.OVERWRITE) const tabInFocusRef = React.useRef(true) @@ -170,6 +163,16 @@ export const Metrics = () => { } } + const refreshMetricsData = () => { + const now = new Date() + const dateFrom = subMinutes(now, durationInMinutes[duration]) + const dateTo = now + eventBus.publish(EventType.METRICS_REFRESH_DATA, { + dateFrom, + dateTo, + }) + } + const handleRemoveMetric = (metric: Metric) => { if (buffer?.id && buffer?.metricsViewState?.metrics) { updateMetrics( @@ -204,7 +207,7 @@ export const Metrics = () => { tabInFocusRef.current = true if (refreshRateRef.current !== RefreshRate.OFF) { setFetchMode(FetchMode.OVERWRITE) - setLastRefresh(new Date().getTime()) + refreshMetricsData() } }, [refreshRateRef.current]) @@ -221,7 +224,7 @@ export const Metrics = () => { () => { if (!tabInFocusRef.current) return setFetchMode(FetchMode.ROLLING_APPEND) - setLastRefresh(new Date().getTime()) + refreshMetricsData() }, refreshRateInSec > 0 ? refreshRateInSec * 1000 : 0, ) @@ -278,17 +281,11 @@ export const Metrics = () => { if (metricDuration && refreshRate && metricViewMode && sampleBy) { updateBuffer(buffer.id, merged) setFetchMode(FetchMode.OVERWRITE) - setLastRefresh(new Date().getTime()) + refreshMetricsData() } } }, [metricDuration, refreshRate, metricViewMode, sampleBy]) - useEffect(() => { - const now = new Date() - setDateFrom(subMinutes(now, durationInMinutes[duration])) - setDateNow(now) - }, [lastRefresh]) - useEffect(() => { if (refreshRate) { refreshRateRef.current = refreshRate @@ -371,10 +368,7 @@ export const Metrics = () => { setLastRefresh(new Date().getTime())} - > + } @@ -461,8 +455,6 @@ export const Metrics = () => { .sort((a, b) => a.position - b.position) .map((metric, index) => ( { onTableChange={handleTableChange} onColorChange={handleColorChange} onMetricDurationChange={setMetricDuration} - lastRefresh={lastRefresh} fetchMode={fetchMode} rollingAppendLimit={rollingAppendLimit} /> diff --git a/packages/web-console/src/scenes/Editor/Metrics/metric.tsx b/packages/web-console/src/scenes/Editor/Metrics/metric.tsx index f74b7d444..2f8832da4 100644 --- a/packages/web-console/src/scenes/Editor/Metrics/metric.tsx +++ b/packages/web-console/src/scenes/Editor/Metrics/metric.tsx @@ -11,6 +11,7 @@ import { mergeRollingData, SampleBy, getTimeFilter, + MetricsRefreshPayload, } from "./utils" import { widgets } from "./widgets" import { QuestContext } from "../../../providers" @@ -26,6 +27,8 @@ import { TableSelector } from "./table-selector" import { IconWithTooltip } from "../../../components/IconWithTooltip" import { ColorPalette } from "./color-palette" import { subMinutes } from "date-fns" +import { eventBus } from "../../../modules/EventBus" +import { EventType } from "../../../modules/EventBus/types" const MetricInfoRoot = styled(Box).attrs({ align: "center", @@ -41,8 +44,6 @@ const ActionButton = styled(Button)` ` export const Metric = ({ - dateFrom, - dateNow, metric, metricDuration, onRemove, @@ -54,15 +55,13 @@ export const Metric = ({ rollingAppendLimit, sampleBy, }: { - dateFrom: Date - dateNow: Date metric: MetricItem metricDuration: MetricDuration onRemove: (metric: MetricItem) => void onTableChange: (metric: MetricItem, tableId: number) => void onColorChange: (metric: MetricItem, color: string) => void onMetricDurationChange: (duration: MetricDuration) => void - lastRefresh?: number + lastRefresh?: Date fetchMode: FetchMode rollingAppendLimit: number sampleBy: SampleBy @@ -72,6 +71,7 @@ export const Metric = ({ const [data, setData] = useState([[], []]) const [lastNotNull, setLastNotNull] = useState() const [colorPickerOpen, setColorPickerOpen] = useState(false) + const [fromTo, setFromTo] = useState() const tables = useSelector(selectors.query.getTables) @@ -81,11 +81,18 @@ export const Metric = ({ durationInMinutes, ) as [MetricDuration, number][] + const isRollingAppendEnabled = + data && + widgetConfig.querySupportsRollingAppend && + fetchMode === FetchMode.ROLLING_APPEND + const fetchMetric = async () => { - setLoading(true) + if (!fromTo) return + const { dateFrom, dateTo } = fromTo + const timeout = setTimeout(() => setLoading(true), 250) try { - const subtracted = subMinutes(dateNow, durationInMinutes[metricDuration]) - const timeFilter = getTimeFilter(subtracted, dateNow) + const subtracted = subMinutes(dateTo, durationInMinutes[metricDuration]) + const timeFilter = getTimeFilter(subtracted, dateTo) const responses = await Promise.all< | QuestDB.QueryResult | QuestDB.QueryResult @@ -96,10 +103,9 @@ export const Metric = ({ metricDuration, sampleBy, timeFilter, - ...(widgetConfig.querySupportsRollingAppend && - fetchMode === FetchMode.ROLLING_APPEND && { - limit: -rollingAppendLimit, - }), + ...(isRollingAppendEnabled && { + limit: -rollingAppendLimit, + }), }), ), quest.query( @@ -111,12 +117,7 @@ export const Metric = ({ const alignedData = widgetConfig.alignData( responses[0].data as unknown as ResultType[MetricType], ) - if ( - data && - widgetConfig.querySupportsRollingAppend && - fetchMode === FetchMode.ROLLING_APPEND - ) { - console.log(mergeRollingData(data, alignedData, dateFrom)) + if (isRollingAppendEnabled) { setData(mergeRollingData(data, alignedData, dateFrom)) } else { setData(alignedData) @@ -132,6 +133,7 @@ export const Metric = ({ } catch (err) { console.error(err) } finally { + clearTimeout(timeout) setLoading(false) } } @@ -147,11 +149,28 @@ export const Metric = ({ } } + const refreshMetricsData = (payload?: MetricsRefreshPayload) => { + if (payload) { + setFromTo(payload) + } + } + useEffect(() => { - if (lastRefresh && metric.tableId) { + if (metric.tableId && fromTo) { fetchMetric() } - }, [lastRefresh, metric.tableId]) + }, [metric.tableId, fromTo]) + + useEffect(() => { + eventBus.subscribe( + EventType.METRICS_REFRESH_DATA, + refreshMetricsData, + ) + + return () => { + eventBus.unsubscribe(EventType.METRICS_REFRESH_DATA, refreshMetricsData) + } + }, []) if (!data && !loading && metric.tableId) return ( @@ -164,18 +183,20 @@ export const Metric = ({ const tableName = tables.find((t) => t.id === metric.tableId)?.table_name const canZoomToData = - tableName && lastNotNull + fromTo?.dateTo && tableName && lastNotNull ? lastNotNull >= subMinutes( - dateNow, + fromTo.dateTo, minuteDurations[minuteDurations.length - 1][1], ).getTime() : false + if (!fromTo) return null + return ( string @@ -49,7 +49,7 @@ const valuePlugin = ( export const useGraphOptions = ({ data, dateFrom, - dateNow, + dateTo, colors, duration, tickValue = (rawValue) => (+rawValue).toString(), @@ -62,7 +62,7 @@ export const useGraphOptions = ({ const start = dateFrom.getTime() - const end = dateNow.getTime() + const end = dateTo.getTime() const baseAxisConfig: uPlot.Axis = { stroke: theme.color.gray2, diff --git a/packages/web-console/src/scenes/Editor/Metrics/utils.ts b/packages/web-console/src/scenes/Editor/Metrics/utils.ts index cdd47c0c8..b765acb06 100644 --- a/packages/web-console/src/scenes/Editor/Metrics/utils.ts +++ b/packages/web-console/src/scenes/Editor/Metrics/utils.ts @@ -31,6 +31,11 @@ export type Widget = { mapYValue: (rawValue: number) => string } +export type MetricsRefreshPayload = { + dateFrom: Date + dateTo: Date +} + export enum MetricDuration { FIVE_MINUTES = "5m", FIFTEEN_MINUTES = "15m",