zjncs opened a new pull request, #4591:
URL: https://github.com/apache/rocketmq-dashboard/pull/4591

   ### Which Issue(s) This PR Fixes
   
   - Fixes #<issue-id>
   
   ### Brief Description
   
   The Proxy page guards async responses with a monotonically increasing 
request id (`loadRequestId`): every caller captures an id and drops responses 
whose id no longer matches. However, the load effect's cleanup **rewound** the 
counter:
   
   ```tsx
   const requestId = loadRequestId.current;
   void loadProxyNodes();
   return () => {
     loadRequestId.current = requestId + 1;
   };
   ```
   
   Because `loadProxyNodes` itself increments the counter 
(`++loadRequestId.current`), the cleanup's assignment could move the counter 
**backwards** to an id that was already issued. After a re-run of the effect 
(e.g. a language switch, since the callback closes over the translated 
strings), the new load and an older still-in-flight mutation could both pass 
the staleness guard, letting the stale response overwrite the fresh list. The 
same rewind also un-matched the `finally` blocks of `handleAddProxyAddress` / 
`handleRemoveProxyAddress`, which clear their button spinner only when their 
captured id still matches — so the add/remove spinner could stay wedged in the 
loading state.
   
   The fix makes the cleanup advance the counter (`loadRequestId.current += 
1`), so ids are never reused and every in-flight request from the previous 
effect run is invalidated. Additionally, the per-mutation spinner state 
(`addressMutationLoading`, `removingProxyAddress`) now clears unconditionally 
in `finally`, because it tracks that mutation's own lifecycle rather than the 
page's load lifecycle — leaving it tied to the id would wedge the button when 
the response arrives stale.
   
   ### How Did You Test This Change?
   
   New test `does not let a stale add overwrite the list reloaded after a 
language switch`: it starts an add (deferred), switches the language to re-run 
the load effect, resolves the fresh load with the post-add list, then resolves 
the older add with the pre-add list. Before the fix, the stale add overwrote 
the list (the just-added address disappeared) and the success toast fired; 
after the fix the list keeps the fresh state and no toast is shown. A test-only 
`LangSwitcher` inside the same `LangProvider` reproduces the effect re-run that 
a real language switch triggers.
   
   ```
   $ NODE_OPTIONS=--no-experimental-webstorage npx --prefix web vitest run 
--root web src/pages/studio/__tests__/Proxy.test.tsx
    Test Files  1 passed (1)
         Tests  16 passed (16)          # 15 before this change; the new test 
fails on master's code
   
   $ npx --prefix web eslint --fix web/src/pages/studio/Proxy.tsx 
web/src/pages/studio/__tests__/Proxy.test.tsx
   $ npx --prefix web tsc -p web --noEmit     # clean
   ```
   
   (`NODE_OPTIONS=--no-experimental-webstorage` is only needed on Node ≥ 25, 
where native `localStorage` shadows jsdom's.) The full web suite (122 files / 
1035 tests) was also run; the Proxy file passed, and the handful of unrelated 
failures were re-run individually and all passed (timeout flakes under heavy 
machine load, ~15 min per test vs 91 s for the whole suite normally).
   
   ### Checklist
   
   - [x] One coherent change; unrelated modifications are not bundled in
   - [x] Commit subject follows Conventional Commits (`feat:` / `fix:` / 
`refactor:` / `chore:` / `docs:` / `perf:`)
   - [x] Tests added or updated for non-trivial changes, test methods named 
`...Test`
   - [x] New UI text has both Chinese and English entries under `web/src/i18n/` 
(no new UI text)
   - [x] Architecture constraints stay green (`mvn test` runs the ArchUnit 
checks) (frontend-only change)
   - [x] New source files carry the ASF license header (no new files)
   - [x] Documentation touched where behaviour changed (bug fix only, no 
behaviour change visible to document)


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