Skip to content

fix: add guard against concurrent execution in DeleteModal#1088

Open
Snehadas2005 wants to merge 3 commits into
kubeflow:notebooks-v2from
Snehadas2005:fix-deletemodal
Open

fix: add guard against concurrent execution in DeleteModal#1088
Snehadas2005 wants to merge 3 commits into
kubeflow:notebooks-v2from
Snehadas2005:fix-deletemodal

Conversation

@Snehadas2005
Copy link
Copy Markdown

Fixes #1042

Rapidly hitting the "Enter" key or clicking the "Delete" button twice in the DeleteModal could trigger multiple duplicate API calls. This occurred because React's asynchronous state updates were too slow to block subsequent event triggers within the same render cycle.

This PR implements a synchronous guard to ensure only one deletion request is processed at a time.

Changes:

  • Synchronous Lock: Introduced a useRef guard (isDeletingRef) to block concurrent execution before the next render cycle immediately.
  • HandleDelete Cleanup: Restructured the handleDelete function to verify the lock and reset it only upon failure, ensuring the action is "one-shot" per modal session.

@github-project-automation github-project-automation Bot moved this to Needs Triage in Kubeflow Notebooks May 8, 2026
@google-oss-prow google-oss-prow Bot added the area/frontend area - related to frontend components label May 8, 2026
@google-oss-prow google-oss-prow Bot requested review from caponetto and thaorell May 8, 2026 07:25
@google-oss-prow google-oss-prow Bot added area/v2 area - version - kubeflow notebooks v2 size/M labels May 8, 2026
Copy link
Copy Markdown

@thaorell thaorell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Snehadas2005, good work here. The comment I left is not a blocking issue, so let me know how it goes

}) => {
const { isMUITheme } = useThemeContext();
const [inputValue, setInputValue] = useState('');
const [isDeleting, setIsDeleting] = useState(false);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider removing isDeleting state to avoid maintaining both ref and state and having the Cancel button always visible. Test to see if hitting the Cancel button while deleting causes any problem

@Snehadas2005
Copy link
Copy Markdown
Author

Thank you for the suggestion @thaorell! I have pushed an update that removes the isDeleting state entirely, as the ActionButton already manages its own internal loading state. I also tested hitting Cancel while a deletion is active; the modal closes cleanly, and the deletion completes successfully in the background without throwing any errors.

Copy link
Copy Markdown

@thaorell thaorell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@thaorell
Copy link
Copy Markdown

/ok-to-test

Copy link
Copy Markdown

@paulovmr paulovmr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Snehadas2005 , thanks for the pull request! I've reviewed and made one comment for a change, if you could take a look please. Also, could you please consider adding some test to cover this behavior?

onClose();
} catch (err) {
setError(extractErrorMessage(err));
isDeletingRef.current = false;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider having this line on the finally instead of the catch block.

Signed-off-by: Sneha Das <154408198+Snehadas2005@users.noreply.github.com>
@google-oss-prow
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from paulovmr. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Signed-off-by: Sneha Das <154408198+Snehadas2005@users.noreply.github.com>

add: test file for DeleteModal

Signed-off-by: Sneha Das <154408198+Snehadas2005@users.noreply.github.com>

fix: Add guard against concurrent DeleteModal execution

Signed-off-by: Sneha Das <154408198+Snehadas2005@users.noreply.github.com>

Update package-lock.json to resolve dependency conflicts

Signed-off-by: Sneha Das <154408198+Snehadas2005@users.noreply.github.com>

fix: lint error and updated esbuild version

Signed-off-by: Sneha Das <154408198+Snehadas2005@users.noreply.github.com>
Signed-off-by: Sneha Das <154408198+Snehadas2005@users.noreply.github.com>
@Snehadas2005 Snehadas2005 marked this pull request as ready for review May 27, 2026 19:01
@google-oss-prow google-oss-prow Bot requested a review from thaorell May 27, 2026 19:01
@Snehadas2005
Copy link
Copy Markdown
Author

Hi @paulovmr, thank you for the review!
I refactored the delete handler to place isDeletingRef.current = false; in a finally block for cleaner execution. I have also added the requested unit tests for DeleteModal.tsx to cover the loading/deleting state lifecycle.
Ready for your feedback! 🤗

"classnames": "^2.2.6",
"date-fns": "^4.1.0",
"dompurify": "^3.2.4",
"esbuild": "0.28.0",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Snehadas2005, can you remove this package?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/frontend area - related to frontend components area/v2 area - version - kubeflow notebooks v2 ok-to-test size/XXL

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

3 participants