unbridled-41 opened a new pull request, #4888:
URL: https://github.com/apache/rocketmq-dashboard/pull/4888
## Problem
Metrics Explorer: if the operator switches the display language while a
**custom PromQL query is still running**, the custom panel never leaves its
spinner — the chart never appears, the Run button stays busy and unclickable,
and the refresh action stays disabled. Only a page reload recovers the view.
## Evidence
`web/src/components/MetricsExplorer.tsx` (base `1ef5d860`):
- `runCustomQuery` marks the panel loading, then publishes only if its
generation is still current: `const currentRequest =
++customRequestIdRef.current;` … `if (currentRequest ===
customRequestIdRef.current)` (the loading flag is set at the top and cleared
only inside those two guarded branches).
- The profiles effect ends with `return () => { cancelled = true;
panelRequestIdRef.current += 1; customRequestIdRef.current += 1; };` while its
body only restarts the **panel** flow through `loadAll(...)`. Nothing restarts
the custom flow.
- That effect depends on `loadAll`, whose dependency chain is `[instanceId,
queryErrorFallback, runQuery]` → `runQuery` deps `[copy.defaultDataSource,
instanceId]`. `queryErrorFallback` (`'Prometheus 查询失败'` / `'Prometheus query
failed'`) and `copy.defaultDataSource` / `copy.customTitle` are values of the
current language, so **switching the language rebuilds the callbacks and
re-runs the effect** — the only other trigger is the instance prop.
Reproduction (deterministic Vitest,
`web/src/components/__tests__/MetricsExplorer.test.tsx` › `keeps the pending
custom query when the display language changes`): hold the custom query's
`queryMetrics` promise open, run it, click the language switch, then resolve
it. On the unfixed source the panel result never renders (`Unable to find an
element with the text: cluster=prod / query=custom`) and the profile list is
refetched (`listMetricProfiles` called twice); with the fix both hold.
Second symptom of the same dependency: the language switch re-queried
*every* profile panel (one Prometheus request per panel) and refetched the
profile list, for a change that has nothing to do with the query.
## Root cause
Display text was part of the query identity. Because
`copy`/`queryErrorFallback` sat in the callbacks' dependency arrays, a language
switch looked like a query-context change, and the profiles effect's cleanup
discarded the in-flight custom query that its body never restarts.
## Fix
The three labels the callbacks need (`defaultDataSource`, `customTitle`,
`queryErrorFallback`) are mirrored in a ref (`queryLabelsRef`) that
`runQuery`/`loadAll`/`runCustomQuery` read, and the callbacks now depend on the
instance only. Rendering keeps reading the live `copy`, so the visible text
still follows the language; only the callbacks' identity is
language-independent, and the profiles effect re-runs for the query context it
was written for.
## Tests
- `npx vitest run src/components/__tests__/MetricsExplorer.test.tsx` → **30
passed** (29 pre-existing + the new regression).
- Pre-fix failure of the new test (source only reverted, test kept):
`AssertionError: expected "vi.fn()" to be called 1 times, but got 2 times`, and
with the two call-count assertions pointed at the panel symptom instead,
`Unable to find an element with the text: cluster=prod / query=custom`.
- `npx vitest run src/components` → **88 passed** (8 files).
- `npx tsc --noEmit` → clean; `npx eslint src/components/MetricsExplorer.tsx
src/components/__tests__/MetricsExplorer.test.tsx` → clean.
## Scoring
PRIORITY 62 (impact 24: the monitoring view is left unusable until reload,
the same failure class as #3304; reach 12: the language switch is a top-bar
control and the window is the query duration; reproducibility 16: deterministic
test; maintenance value 10: removes a duplicate Prometheus fan-out).
FIX_CONFIDENCE 90.
## Risk
Low. The ref mirrors strings, so its effect is quiet between language
switches; messages already on screen keep the language they were produced in
until the next query, which is how the rest of the page's stored error text
already behaves. The instance-transition and data-source paths are untouched
(the test `re-runs the committed custom query when the dashboard instance
changes` still passes), so the #3299 guards keep working.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]