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]

Reply via email to