ui/db-console: fix duplicate TS query requests on dashboard switch#162612
Open
dhartunian wants to merge 1 commit intocockroachdb:masterfrom
Open
ui/db-console: fix duplicate TS query requests on dashboard switch#162612dhartunian wants to merge 1 commit intocockroachdb:masterfrom
dhartunian wants to merge 1 commit intocockroachdb:masterfrom
Conversation
Note(davidh): this investigation, conclusions, and fix was done by
Claude. Keeping a detailed transcript here for posterity. I believe it's
correct after reviewing.
When switching dashboards via the dropdown on the Metrics page, time
series queries were dispatched multiple times with different time
windows, resulting in duplicate HTTP requests to `/ts/query`. This
doubled the load on the time series infrastructure.
The root cause was a chain of events triggered by the dashboard switch:
1. `ErrorBoundary` uses `key={pathname}`, so the entire subtree
unmounts and remounts when the dashboard path changes.
2. `setClusterPath` called `history.push(path)` without preserving
query params, so `?preset=past-hour` was lost from the URL.
3. On remount, `TimeScaleDropdownWithSearchParams`'s `useEffect([])`
fired. With no URL params, the else branch called
`onTimeScaleChange(props.currentScale)`, which dispatched
`SET_SCALE` with the already-current scale.
4. The `SET_SCALE` reducer set `shouldUpdateMetricsWindowFromScale =
true` even though the scale hadn't changed.
5. `MetricsTimeManager` (mounted above the ErrorBoundary, stays alive)
saw the flag, called `setWindow` with a new "now" timestamp T2
(slightly different from the existing T1).
6. `MetricsDataProviders` that already dispatched requests with T1 in
`componentDidMount` now saw changed `timeInfo` (T2) and dispatched
a second round of requests in `componentDidUpdate`.
7. The saga's `delay(0)` batching window collected both T1 and T2
requests, grouped them into separate batches by timespan, and sent
multiple HTTP requests.
Three changes fix this:
- Preserve query params in `setClusterPath` by passing
`{ pathname, search }` to `history.push` instead of just the path
string. This keeps `?preset=past-hour` in the URL across dashboard
switches.
- Skip the `SET_SCALE` dispatch in `TimeScaleDropdownWithSearchParams`
when the URL has `?preset=X` and the redux store already has the
matching preset with a moving window.
- In the else branch (no URL params), call `updateUrlParams` instead
of `onTimeScaleChange` to sync the URL without dispatching
`SET_SCALE`.
Also removes a dead `requests = []` assignment that cleared a
function parameter after it was already consumed.
Fixes: cockroachdb#158507
Release note: None
Epic: None
Contributor
|
Merging to
|
Member
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note(davidh): this investigation, conclusions, and fix was done by Claude. Keeping a detailed transcript here for posterity. I believe it's correct after reviewing.
When switching dashboards via the dropdown on the Metrics page, time series queries were dispatched multiple times with different time windows, resulting in duplicate HTTP requests to
/ts/query. This doubled the load on the time series infrastructure.The root cause was a chain of events triggered by the dashboard switch:
ErrorBoundaryuseskey={pathname}, so the entire subtree unmounts and remounts when the dashboard path changes.setClusterPathcalledhistory.push(path)without preserving query params, so?preset=past-hourwas lost from the URL.On remount,
TimeScaleDropdownWithSearchParams'suseEffect([])fired. With no URL params, the else branch calledonTimeScaleChange(props.currentScale), which dispatchedSET_SCALEwith the already-current scale.The
SET_SCALEreducer setshouldUpdateMetricsWindowFromScale = trueeven though the scale hadn't changed.MetricsTimeManager(mounted above the ErrorBoundary, stays alive) saw the flag, calledsetWindowwith a new "now" timestamp T2 (slightly different from the existing T1).MetricsDataProvidersthat already dispatched requests with T1 incomponentDidMountnow saw changedtimeInfo(T2) and dispatched a second round of requests incomponentDidUpdate.The saga's
delay(0)batching window collected both T1 and T2 requests, grouped them into separate batches by timespan, and sent multiple HTTP requests.Three changes fix this:
Preserve query params in
setClusterPathby passing{ pathname, search }tohistory.pushinstead of just the path string. This keeps?preset=past-hourin the URL across dashboard switches.Skip the
SET_SCALEdispatch inTimeScaleDropdownWithSearchParamswhen the URL has?preset=Xand the redux store already has the matching preset with a moving window.In the else branch (no URL params), call
updateUrlParamsinstead ofonTimeScaleChangeto sync the URL without dispatchingSET_SCALE.Also removes a dead
requests = []assignment that cleared a function parameter after it was already consumed.Fixes: #158507
Release note: None
Epic: None