From 946e69bbd272ba2e8e870ba61febd4cc2cb1c0e1 Mon Sep 17 00:00:00 2001 From: Jacques Ikot Date: Mon, 22 Apr 2024 03:30:56 +0100 Subject: [PATCH] fix: race condition when running building block actions after drop on canvas (#32808) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description > [!TIP] After a building block has been dropped, all queries within the building block that are set to run onPageLoad are triggered. We noticed that when dropping multiple building blocks, there was a race condition causing some queries ro run infinitely. After inspecting, we found that running the actions sequentially will solve the problem. These building block actions are limited to a max of 3. ## Automation /ok-to-test tags="@tag.Sanity" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: 81a2a65c53cc90f817c24d3a003f9ec85acc1428 > Cypress dashboard url: Click here! ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No ## Summary by CodeRabbit - **Refactor** - Improved the execution flow of actions in the widget addition process to enhance performance and reliability. --- app/client/src/sagas/WidgetAdditionSagas.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/app/client/src/sagas/WidgetAdditionSagas.ts b/app/client/src/sagas/WidgetAdditionSagas.ts index 81857b53af..9cfbfb05e9 100644 --- a/app/client/src/sagas/WidgetAdditionSagas.ts +++ b/app/client/src/sagas/WidgetAdditionSagas.ts @@ -616,27 +616,29 @@ function* getBuildingBlocksDropMousePosition( return mousePosition; } +function* runSingleAction(actionId: string) { + yield put(runAction(actionId)); + yield take(ReduxActionTypes.RUN_ACTION_SUCCESS); +} + function* runNewlyCreatedActions( actionsBeforeAddingBuildingBlock: ActionDataState, actionsAfterAddingBuildingBlocks: ActionDataState, ) { - // Extract unique ids from the actionsBeforeAddingBuildingBlocks array const actionIdsBeforeAddingBB = actionsBeforeAddingBuildingBlock.map( (obj) => obj.config.id, ); - // Filter the after array to find new actions not present in actionsBeforeAddingBuildingBlocks array const newlyAddedActions = actionsAfterAddingBuildingBlocks.filter( (obj) => !actionIdsBeforeAddingBB.includes(obj.config.id), ); - // run all newly created actions - if (newlyAddedActions && newlyAddedActions.length > 0) { - yield all( - newlyAddedActions.map(function* (action) { - yield put(runAction(action.config.id)); - }), - ); + // Run each action sequentially. We have a max of 2-3 actions per building block. + // If we run this in parallel, we will have a racing condition when multiple building blocks are drag and dropped quickly. + for (const action of newlyAddedActions) { + if (action.config.executeOnLoad) { + yield runSingleAction(action.config.id); + } } }