unbridled-41 opened a new pull request, #4590:
URL: https://github.com/apache/rocketmq-dashboard/pull/4590

   Fixes #4589.
   
   ## Problem / Evidence
   
   The instance discovery effect on the broker topology page writes the first 
Apache-capable instance into the selection on every run:
   
   ```tsx
     useEffect(() => {
       let active = true;
       void listInstances()
         .then((nextInstances) => {
           …
           setSelectedInstanceId(apacheInstances[0]?.name);      // :236, 
unconditional
         })
         …
     }, [clearData, message, t]);                                // :246
   ```
   
   `t` is recreated whenever the display language changes 
(`web/src/i18n/LangContext.tsx`), while `clearData` and `message` are stable — 
so the top-bar language toggle re-runs the effect and overwrites the instance 
the user selected. The data below then reloads for that other instance. The 
twin page already guards the identical write 
(`web/src/pages/studio/Producer.tsx:104-108`), which is the intended contract.
   
   Reproduced by the regression test added here: it selects `instance-2`, 
switches the language through the real `LangProvider.setLang`, and asserts both 
the loaded topology and the instance the page queries.
   
   ## Root cause / Fix
   
   An effect that both discovers instances and seeds the default selection, 
keyed on a dependency that changes for an unrelated reason (rendering text in 
another language). The minimal fix is the guard the sibling page uses — the 
effect may re-run, but it only replaces a selection that is no longer valid:
   
   ```diff
            const apacheInstances = nextInstances.filter(supportsApacheRuntime);
            setInstances(apacheInstances);
   -        setSelectedInstanceId(apacheInstances[0]?.name);
   +        setSelectedInstanceId((current) =>
   +          apacheInstances.some((instance) => instance.name === current)
   +            ? current
   +            : apacheInstances[0]?.name,
   +        );
   ```
   
   A first visit still selects the first Apache instance, and an instance that 
disappeared from the list still falls back — only a re-run for an unrelated 
reason keeps the user's choice.
   
   ## Priority & scoring
   
   - PRIORITY **70** = impact 26 + blast radius 9 + reproducibility 20 + 
maintenance value 15
     - impact 26 — the page silently switches to another instance's 
broker/nameserver/proxy topology; a refresh or a routine language toggle is 
enough to make the user read the wrong instance's data.
     - blast radius 9 — one page, but it is the page used to inspect broker 
topology in multi-instance deployments; the topology is also the input to the 
config actions on that page.
     - reproducibility 20 — deterministic; the regression test drives the real 
language switch and fails on `master`.
     - maintenance value 15 — the same effect exists on the producer page with 
the guard in place; aligning them removes the divergence.
   - FIX_CONFIDENCE **95** — the sibling implementation defines the expected 
behaviour exactly, the change is three lines, and the page's other 15 tests 
(including "clears topology from the previous instance when the next instance 
fails to load") still pass.
   
   ## Tests
   
   Environment: Node 24.20.0, `web/` at the PR head.
   
   Red — base source (`d50ffecc`) with the new test:
   
   ```
   $ git checkout origin/master -- web/src/pages/studio/BrokerCluster.tsx
   $ npx vitest run 
src/pages/studio/__tests__/BrokerClusterInstanceScope.test.tsx
    FAIL  src/pages/studio/__tests__/BrokerClusterInstanceScope.test.tsx > 
BrokerCluster instance scope > keeps the instance the user selected when the 
display language changes
   AssertionError: expected last "vi.fn()" call to have been called with [ 
'instance-2' ]
   
   - Expected
   + Received
   
     [
   -   "instance-2",
   +   "instance-1",
     ]
   
    ❯ src/pages/studio/__tests__/BrokerClusterInstanceScope.test.tsx:160:46
   
    Test Files  1 failed (1)
         Tests  1 failed (1)
   ```
   
   Green — with the fix, including the page's existing suite:
   
   ```
   $ npx vitest run 
src/pages/studio/__tests__/BrokerClusterInstanceScope.test.tsx \
                    src/pages/studio/__tests__/BrokerCluster.test.tsx
    Test Files  2 passed (2)
         Tests  16 passed (16)
   ```
   
   Full suite:
   
   ```
   $ npx vitest run --maxWorkers=4
    Test Files  1 failed | 122 passed (123)
         Tests  1 failed | 1034 passed (1035)
   ```
   
   `1035 = 1034 (pristine origin/master) + 1 new test`. The single failure is 
`ConsumerPage.test.tsx > keeps the latest client stack when an older request 
resolves last` — a file this PR does not touch and one of the load-fragile 
cases on this repository (the same file also fails intermittently on pristine 
`master` under a full parallel run). Isolating it:
   
   ```
   $ npx vitest run src/pages/instance/__tests__/ConsumerPage.test.tsx
    Test Files  1 passed (1)
         Tests  32 passed (32)
   ```
   
   Static checks:
   
   ```
   $ npx tsc -b             # clean, exit 0
   $ npx eslint src/pages/studio/BrokerCluster.tsx 
src/pages/studio/__tests__/BrokerClusterInstanceScope.test.tsx
                            # no output: 0 errors, 0 warnings
   $ npm run build          # ✓ built in 12.48s
   ```
   
   Diff: `web/src/pages/studio/BrokerCluster.tsx` +5/−1, 
`web/src/pages/studio/__tests__/BrokerClusterInstanceScope.test.tsx` +165/−0 
(`git show --numstat`).
   
   ## Risk
   
   - The effect still re-runs on a language change (it re-reads the instance 
list and re-renders its labels); only the destructive part — replacing a 
still-valid selection — is removed. Making the effect mount-only would 
additionally require routing the failure message through a ref; that is 
deliberately left out to keep this change to the reported defect.
   - Fallback behaviour is unchanged for the cases that need it: no instances → 
`undefined` selection, selected instance removed from the list → first Apache 
instance.
   - No API, contract or translation-key changes.
   


-- 
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]

Reply via email to