tju-yxq opened a new issue, #5407:
URL: https://github.com/apache/rocketmq-dashboard/issues/5407
## Problem
The add-instance modal runs **two mutations without mutual exclusion**.
Create and update share a `mutationInFlightRef` guard — the page's own test
pins the intent ("ignores duplicate create submissions while the first request
is pending") — but the cloud vendors' 一键导入 (one-click import) bypasses it
entirely: `handleImportAll` checks only its own `importing` flag. While Connect
is pending, the import button is fully active; while an import is running,
Connect is fully active. Starting the second mutation interleaves two modal
lifecycles: both handlers close and reset the modal and reload the instance
list on completion, so whichever finishes first closes/resets the modal under
the still-pending winner, which then lands its own success toast and a second
list reload — the operator sees the modal snap shut and reopen state vanish
mid-action, with a garbled sequence of toasts and reloads.
## What did you do (steps to reproduce)?
1. Open **实例管理 > 添加实例**, switch to a cloud vendor tab (e.g., Aliyun 版) and
select a credential.
2. Fill the form and click 连接; while the request is on the wire (a slow
backend makes this easy), click 一键导入 — it is not disabled.
3. The import runs concurrently with the create: the modal is closed/reset
by whichever finishes first and the list is reloaded twice with interleaved
results.
The reverse order (import first, then Connect) behaves the same way.
## What did you expect to see?
The modal enforces one mutation at a time, as it already does between create
and update.
## What did you see instead?
Import and create/update run concurrently and fight over the modal's
lifecycle.
## Root cause
`web/src/pages/instance/index.tsx`:
- Line 147: `const mutationInFlightRef = useRef(false);` — the shared guard.
- Lines 348-349 (`handleCreate`) and 437-438 (`handleUpdate`): both check
and set the ref.
- Lines 380-387 (`handleImportAll`): `if (importing || vendor === 'APACHE')
return;` — only its own flag; the ref is neither checked nor set.
- Footer buttons (lines 790-817): the import button is `loading={importing}
disabled={!addCredentialId}` and Connect is `loading={submitting}` — neither
reflects the other's flight.
## Expected behavior
- `handleImportAll` participates in `mutationInFlightRef`: an import cannot
start while create/update is in flight, and vice versa.
- The footer buttons reflect the cross-flight state: 一键导入 disabled while
submitting, 连接 disabled while importing.
- Each flow's own behavior (validation, toasts, list reload, modal reset) is
unchanged.
## Acceptance criteria
- [ ] Regression proof: on the current code, the import button is enabled
and fires `importCloudInstances` while a create is pending; with the fix it is
disabled and the call never fires.
- [ ] Connect is disabled while an import is running.
- [ ] The existing duplicate-create guard and every other instance-page
behavior are unchanged.
## Environment
Branch `rocketmq-studio` at `6a68042f`; file:
`web/src/pages/instance/index.tsx`.
## Duplicate check
Searched open and closed issues for `instance import`: the import items
(#4656 audit outcome grading, #2675 first-failure abort, #2609 inventory
truncation) cover the import's server-side semantics, not the modal's mutation
guard. Nothing covers import-vs-create concurrency.
--
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]