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

delay graph execution when adding/modifying multiple nodes at once #11230

Merged
merged 15 commits into from
Jan 24, 2021

Conversation

pinzart90
Copy link
Contributor

@pinzart90 pinzart90 commented Nov 3, 2020

Please Note:

  1. Before submitting the PR, please review How to Contribute to Dynamo
  2. Dynamo Team will meet 1x a month to review PRs found on Github (Issues will be handled separately)
  3. PRs will be reviewed from oldest to newest
  4. If a reviewed PR requires changes by the owner, the owner of the PR has 30 days to respond. If the PR has seen no activity by the next session, it will be either closed by the team or depending on its utility will be taken over by someone on the team
  5. PRs should use either Dynamo's default PR template or one of these other template options in order to be considered for review.
  6. PRs that do not have one of the Dynamo PR templates completely filled out with all declarations satisfied will not be reviewed by the Dynamo team.
  7. PRs made to the DynamoRevit repo will need to be cherry-picked into all the DynamoRevit Release branches that Dynamo supports. Contributors will be responsible for cherry-picking their reviewed commits to the other branches after a LGTM label is added to the PR.

Purpose

https://jira.autodesk.com/browse/AGD-1801

Fix slow undo, copy paste, nodeToCode (basically operations applied on many nodes at once that might trigger recomputation).
Added mechanism to delay graph execution (instead of creating many UpdateGraphAsyncTasks for each node that is modified, we create a single UpdateGraphAsyncTask that will contain all modified nodes)

Changes to code follow the example bellow:

// old code, with 100 Nodes
foreach (node in Nodes) {
  workspace.AddAndRegisterNode(node);
}
// => will result in 100 UpdateGraphAsyncTasks, each one with 1 ModifiedNodes
// these will be executed one at a time by the DynamoScheduler 

new code, with 100 Nodes
using(workspace.BeginDelayedGraphExecution)
{
  foreach (node in Nodes) {
    workspace.AddAndRegisterNode(node);
  }
}
// => will result in 1 UpdateGraphAsyncTask with 100 ModifiedNodes
// will be executed by DynamoScheduler 

Declarations

Check these if you believe they are true

  • The codebase is in a better state after this PR
  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • All tests pass using the self-service CI.
  • Snapshot of UI changes, if any.
  • Changes to the API follow Semantic Versioning and are documented in the API Changes document.
  • This PR modifies some build requirements and the readme is updated

Reviewers

(FILL ME IN) Reviewer 1 (If possible, assign the Reviewer for the PR)

(FILL ME IN, optional) Any additional notes to reviewers or testers.

FYIs

(FILL ME IN, Optional) Names of anyone else you wish to be notified of

@pinzart90 pinzart90 added the WIP label Nov 3, 2020
@aparajit-pratap
Copy link
Contributor

@pinzart90 now that you've removed the Run step, when and where does the Run actually take place?

@pinzart90
Copy link
Contributor Author

pinzart90 commented Nov 3, 2020

@pinzart90 now that you've removed the Run step, when and where does the Run actually take place?

undoRecorder.Undo();
// http://adsk-oss.myjetbrains.com/youtrack/issue/MAGN-7883
// Request run for every undo action
RequestRun();

undoRecorder.Undo(); will eventually call the code that I modified.
RequestRun(); will do the Run

Copy link
Contributor

@aparajit-pratap aparajit-pratap left a comment

Choose a reason for hiding this comment

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

One comment.

@pinzart90 pinzart90 added PTAL Please Take A Look 👀 and removed WIP labels Jan 21, 2021
@mjkkirschner
Copy link
Member

looks like 7 test failures.

@pinzart90
Copy link
Contributor Author

looks like 7 test failures.

Thanks, casting issue. Should be fixed now

@pinzart90 pinzart90 changed the title do not register each individual node on undo delay graph execution when adding/modifying multiple nodes at once Jan 21, 2021
// that they were done (due to inter-dependencies among components).
//
for (int index = actions.Count - 1; index >= 0; index--)
using ((undoClient as WorkspaceModel)?.BeginDelayedGraphExecution())
Copy link
Member

Choose a reason for hiding this comment

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

the syntax is pretty neat.

@mjkkirschner
Copy link
Member

There are a few diffs here that are hard to read - are there really that many changes or is that all from wrapping that code in an outer using statement?

@mjkkirschner
Copy link
Member

I think we should probably add simple unit tests for this new class to enforce its behavior though I guess it would be "covered" by its usage as part of undo/redo?

@pinzart90
Copy link
Contributor Author

pinzart90 commented Jan 21, 2021

t all from wrapping that code

Changes are simple, it;s just the indentation of the wrapped code.
@mjkkirschner
You can hide whitespace changes in the review. Access the PR with this link https://github.com/DynamoDS/Dynamo/pull/11230/files?diff=unified&w=1

@pinzart90
Copy link
Contributor Author

I think we should probably add simple unit tests for this new class to enforce its behavior though I guess it would be "covered" by its usage as part of undo/redo?

Wanted a review before adding tests. I will need to add specific tests to target this functionality (even for undo/redo)

/// Class is thread safe, although behavior is not well defined.
/// Nested instance of this class do not have a well defined behavior.
/// </summary>
internal class DelayedGraphExecution : IDisposable
Copy link
Member

@mjkkirschner mjkkirschner Jan 22, 2021

Choose a reason for hiding this comment

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

hmm - I like the new design, what about DelayedWorkspaceExecution for a name? Or is that an implementation detail rather than an API one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm, I'm not convinced that is better or worse

@mjkkirschner
Copy link
Member

@QilongTang if you are going to tackle undo/redo moving of nodes you may want to look at this new internal functionality.

{
workspace.delayGraphExecutionCounter--;
}
workspace.RequestRun();
Copy link
Contributor

@aparajit-pratap aparajit-pratap Jan 22, 2021

Choose a reason for hiding this comment

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

There is a RequestRun call, I think, at the end of each of these actions - undo, redo, convertnodetocode etc, so why call it again here?

Copy link
Contributor Author

@pinzart90 pinzart90 Jan 22, 2021

Choose a reason for hiding this comment

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

DelayedGraphExecution can be used in other cases, besides the ones I covered in this PR
The DelayedGraphExecution class does not know that there will be a RequestRun called after it is used.
In the cases of undo, redo, convertnodetocode etc the requestRun calls (after DelayedGraphExecution) will not register any UpdateGraphAsyncTasks, because there will be no more dirty nodes.

@pinzart90 pinzart90 merged commit fc170b1 into master Jan 24, 2021
@pinzart90 pinzart90 deleted the fix_undo_one_elem_at_a_time branch January 24, 2021 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PTAL Please Take A Look 👀
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants