Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: perf optimisation for js action creation phase 1 #37391

Merged
merged 5 commits into from
Nov 19, 2024

Conversation

sneha122
Copy link
Contributor

@sneha122 sneha122 commented Nov 14, 2024

Description

During analysis of action creation flow metrics, we observed that RefactoringService.isNameAllowed is taking 80-90% of the total JS object action time. This PR optimises this part in a way that for any jsobject action, instead of fetching all actions from DB and comparing it
to see if current action name is allowed, we simply do that check in memory where for current action collection, if any action names are being duplicated, we throw the error.

We could make this change easily because recently we merged a PR which removes the actions with duplicate name from client payload whenever Js object update API is called, with this change, we can guarantee that for any JS object update call, all actions inside it will always have unique names. This PR makes the similar check on backend where if any action has duplicate name within collection, we throw an error and don't store that action in the DB.

We may need to consider following test case in both before and after implementation of this approach. This can be covered during PR testing:
What happens if the client sends multiple requests to add a new function in an existing collection. That is, as a result of the debounce logic, if the server receives 2 consecutive requests with a populated collection but without actionId associated to either request.

Relevant thread: https://theappsmith.slack.com/archives/C040LHZN03V/p1731571364933089

Fixes #37365
or
Fixes Issue URL

Warning

If no issue exists, please create an issue first, and check with the maintainers if the issue is valid.

Automation

/ok-to-test tags="@tag.JS"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/11911295324
Commit: d5c75ed
Cypress dashboard.
Tags: @tag.JS
Spec:


Tue, 19 Nov 2024 11:14:16 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Enhanced validation to prevent the creation of actions with duplicate names in action collections.
    • Simplified handling of JavaScript actions, allowing them to bypass certain validation checks.
  • Bug Fixes

    • Improved error handling during action updates and collection modifications to ensure better logging and management of failures.
  • Tests

    • Added tests to verify that duplicate action names trigger appropriate error messages, enhancing the robustness of the action collection feature.

Copy link
Contributor

coderabbitai bot commented Nov 14, 2024

Walkthrough

The changes in this pull request primarily involve modifications to the LayoutActionServiceCEImpl and LayoutCollectionServiceCEImpl classes, enhancing the handling of JavaScript actions and the validation of action names within collections. The validateAndGenerateActionDomainBasedOnContext method now bypasses name validation for JS actions, while the updateUnpublishedActionCollection method introduces checks to prevent duplicate action names. Additionally, new tests have been added to ensure these validations function correctly.

Changes

File Path Change Summary
.../LayoutActionServiceCEImpl.java - Modified validateAndGenerateActionDomainBasedOnContext to bypass name validation for JS actions.
- Added debug logging in updateActionBasedOnContextType.
.../LayoutCollectionServiceCEImpl.java - Enhanced updateUnpublishedActionCollection to check for duplicate action names and refined error handling.
.../ActionCollectionServiceTest.java - Added tests for duplicate action name handling in action collections.

Assessment against linked issues

Objective Addressed Explanation
Optimize isNameAllowed method in JS object action creation (#37365)

Possibly related issues

Possibly related PRs

Suggested labels

Bug

Suggested reviewers

  • nidhi-nair
  • dvj1988
  • sondermanish

Poem

In the realm of code, where actions play,
JS now dances, in a streamlined way.
Duplicate names, no longer a fright,
With checks in place, all feels just right!
So raise a cheer for the changes made,
In our code's journey, progress is laid! 🎉


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sneha122 sneha122 added the ok-to-test Required label for CI label Nov 14, 2024
@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Nov 14, 2024
Copy link

Failed server tests

  • com.appsmith.server.services.ActionCollectionServiceTest#testUpdateUnpublishedActionCollection_createMultipleActionsWithSameName_returnsDuplicateActionNameError

1 similar comment
Copy link

Failed server tests

  • com.appsmith.server.services.ActionCollectionServiceTest#testUpdateUnpublishedActionCollection_createMultipleActionsWithSameName_returnsDuplicateActionNameError

@github-actions github-actions bot added Integrations Pod General Issues related to the Integrations Pod that don't fit into other tags. Integrations Product Issues related to a specific integration Javascript Product Issues related to users writing javascript in appsmith JS Objects Issues related to JS Objects Query & JS Pod Issues related to the query & JS Pod Task A simple Todo labels Nov 14, 2024
Copy link

Failed server tests

  • com.appsmith.server.services.ActionCollectionServiceTest#testUpdateUnpublishedActionCollection_createMultipleActionsWithSameName_returnsDuplicateActionNameError

@sneha122 sneha122 removed the ok-to-test Required label for CI label Nov 14, 2024
Copy link

Failed server tests

  • com.appsmith.server.services.ce.ApplicationServiceCETest#validGetApplicationById

@sneha122 sneha122 added the ok-to-test Required label for CI label Nov 15, 2024
@sneha122 sneha122 marked this pull request as ready for review November 15, 2024 08:19
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java (1)

870-928: LGTM! Consider extracting common test setup.

The test effectively validates handling of multiple actions with duplicate names. Consider extracting the common setup code (action collection creation, mock setup) into a helper method to improve maintainability.

+ private ActionCollectionDTO createTestActionCollection(String name, String actionName) {
+     ActionCollectionDTO actionCollectionDTO = new ActionCollectionDTO();
+     actionCollectionDTO.setName(name);
+     actionCollectionDTO.setPageId(testPage.getId());
+     actionCollectionDTO.setApplicationId(testApp.getId());
+     actionCollectionDTO.setWorkspaceId(workspaceId);
+     actionCollectionDTO.setPluginId(datasource.getPluginId());
+     actionCollectionDTO.setVariables(List.of(new JSValue("test", "String", "test", true)));
+     actionCollectionDTO.setBody("collectionBody");
+     actionCollectionDTO.setPluginType(PluginType.JS);
+
+     ActionDTO action = new ActionDTO();
+     action.setName(actionName);
+     action.setActionConfiguration(new ActionConfiguration());
+     action.getActionConfiguration().setBody("initial body");
+     action.getActionConfiguration().setIsValid(false);
+     actionCollectionDTO.setActions(List.of(action));
+
+     return actionCollectionDTO;
+ }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 17537e7 and d5c75ed.

📒 Files selected for processing (3)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java (1 hunks)
  • app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java (2 hunks)
  • app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java (3 hunks)
🔇 Additional comments (4)
app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutActionServiceCEImpl.java (1)

439-446: Verify client-side validation for JS action names

While bypassing server-side validation for JS actions improves performance, we need to ensure that client-side validation is robust.

Consider adding debug logs before the conditional check:

+    log.debug("Validating action name. Action type: {}, Name: {}", isJsAction ? "JS" : "Non-JS", name);
     if (!isJsAction) {
         return refactoringService
             .isNameAllowed(page.getId(), contextType, layout.getId(), name)
             .name(IS_NAME_ALLOWED)
             .tap(Micrometer.observation(observationRegistry));
     }
+    log.debug("Skipping name validation for JS action: {}", name);
     return Mono.just(true);
app/server/appsmith-server/src/main/java/com/appsmith/server/services/ce/LayoutCollectionServiceCEImpl.java (2)

318-325: LGTM! Efficient approach for duplicate name validation.

The stream-based implementation efficiently validates unique action names in memory before any DB operations.


346-358: Consider adding transaction boundary for concurrent action creation.

While the duplicate name check works for single requests, there's a potential race condition when multiple requests attempt to create actions with the same name simultaneously. Consider wrapping the name check and action creation in a transaction.

Let's verify if there are any existing transaction boundaries:

app/server/appsmith-server/src/test/java/com/appsmith/server/services/ActionCollectionServiceTest.java (1)

810-868: LGTM! Well-structured test for duplicate action name validation.

The test effectively validates the error handling when attempting to create a new action with the same name as an existing one.

Copy link
Contributor

@NilanshBansal NilanshBansal left a comment

Choose a reason for hiding this comment

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

LGTM

@sneha122 sneha122 added ok-to-test Required label for CI and removed ok-to-test Required label for CI labels Nov 19, 2024
@sneha122 sneha122 merged commit 7612e4f into release Nov 19, 2024
193 of 199 checks passed
@sneha122 sneha122 deleted the chore/in-memory-is-name-allowed-js-actions branch November 19, 2024 11:34
github-actions bot pushed a commit to Zeral-Zhang/appsmith that referenced this pull request Nov 20, 2024
…37391)

## Description

[During analysis of action creation flow
metrics](appsmithorg#37151 (comment)),
we observed that RefactoringService.isNameAllowed is taking 80-90% of
the total JS object action time. This PR optimises this part in a way
that for any jsobject action, instead of fetching all actions from DB
and comparing it
to see if current action name is allowed, we simply do that check in
memory where for current action collection, if any action names are
being duplicated, we throw the error.

We could make this change easily because recently we merged a
[PR](appsmithorg#36958) which removes
the actions with duplicate name from client payload whenever Js object
update API is called, with this change, we can guarantee that for any JS
object update call, all actions inside it will always have unique names.
This PR makes the similar check on backend where if any action has
duplicate name within collection, we throw an error and don't store that
action in the DB.

We may need to consider following test case in both before and after
implementation of this approach. This can be covered during PR testing:
What happens if the client sends multiple requests to add a new function
in an existing collection. That is, as a result of the debounce logic,
if the server receives 2 consecutive requests with a populated
collection but without actionId associated to either request.

Relevant thread:
https://theappsmith.slack.com/archives/C040LHZN03V/p1731571364933089

Fixes appsmithorg#37365 
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.JS"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/11911295324>
> Commit: d5c75ed
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=11911295324&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.JS`
> Spec:
> <hr>Tue, 19 Nov 2024 11:14:16 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced validation to prevent the creation of actions with duplicate
names in action collections.
- Simplified handling of JavaScript actions, allowing them to bypass
certain validation checks.

- **Bug Fixes**
- Improved error handling during action updates and collection
modifications to ensure better logging and management of failures.

- **Tests**
- Added tests to verify that duplicate action names trigger appropriate
error messages, enhancing the robustness of the action collection
feature.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: “sneha122” <“[email protected]”>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Integrations Pod General Issues related to the Integrations Pod that don't fit into other tags. Integrations Product Issues related to a specific integration Javascript Product Issues related to users writing javascript in appsmith JS Objects Issues related to JS Objects ok-to-test Required label for CI Query & JS Pod Issues related to the query & JS Pod skip-changelog Adding this label to a PR prevents it from being listed in the changelog Task A simple Todo
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Task]: Optimise isNameAllowed method in JS object action creation
3 participants