Skip to content

Conversation

@ke-yu
Copy link
Contributor

@ke-yu ke-yu commented Mar 10, 2016

Purpose

Fix MAGN-9568 Crash in preview control

There are two issues, both related to outdated mirror data that used in preview control to query the node value from the DesignScript virtual machine.

Updating a graph will update mirror data in all executed UI nodes. Ideally, the following preview operation will get the latest mirror data to display value. But because updating graph (UpdateGraphAsyncTask), querying mirror data (QueryMirrorDataAsyncTask) and displaying preview value (wrapped in DelegateBasedAsyncTask) are all asynchronous operations, and their creation is not necessarily in scheduler thread, their execution order is not guaranteed and the outdated mirror data will be used and cause crash.

The first issue is DelegateBasedAsyncTask is scheduled before QueryMirrorDataAsyncTask.

In this case, UpdateGraphAsyncTask has been executed and node's value has been updated. Now a DelegateBasedAsyncTask is created and put in scheduler thread (because of previewing operation on the UI thread). It will be executed immediately because QueryMirrorDataAsyncTaskhas not been scheduled yet:

Scheduler task queue
--------------------

         +----------if complete, schedule query task -----+
         |                                                |
         |                                                v
+----------------------+------------------------+--------------------------+
| UpdateGraphAsyncTask | DelegateBasedAsyncTask | QueryMirrorDataAsyncTask |
+----------------------+------------------------+--------------------------+
                                ^
                                |
                                +----- Scheduled from UI thread

NodeModel.CachedValue has not been updated yet, but the value of node has been changed, so NodeModel.CachedValue becomes invalid.

There are three ways to fix this case:

  1. Set NodeModel.CachedValue to some invalid state. In DelegateBasedAsyncTask we will check if mirror data is invalid or not, and display "..." in the preview control accordingly. Mirror data will finally be updated in QueryMirrorDataAsyncTask. But introducing more states will make the code be harder to maintain.
  2. As MirrorData is a snapshot of value, we could add the other kind of mirror data which always reflects current value. But MirrorData is widely used now, making this change will incur too many other changes. Besides, always querying value from the engine would be a potential performance issue.
  3. Or, immediately updating mirror data after UpdateGraphAysncTask is executed. Firstly, it is a trivial change; secondly, if we can ensure all these operations happen in scheduler thread, DelegateBasedAsyncTask would never get a change to kick in and get executed. This PR uses this option.

Related change: NodeModel.RequestValueUpdateAsync() is updated to synchronous NodeModel.RequestValueUpdate().

The second issue is, PreviewControl holds a cached of mirror data (PreviewControl.mirrordata), this mirrordata will only be updated after UpdateGraphAsyncTask is scheduled, but before that, DelegateBasedAsyncTask may be scheduled already:

Scheduler task queue
--------------------

         +----------if complete, update preview control's mirror data .....
         |                                                                +
         |                                                                |
+----------------------+------------------------+                         |
| UpdateGraphAsyncTask | DelegateBasedAsyncTask |                         |
+----------------------+------------------------+                         |
                                ^                                         |
                                |                                         |
                        Scheduled from UI thread                           |
                                                                          v
                                                     Update preview control's mirror data

Again, invalid mirror data is used.

As PreviewControl knows about NodeModel, it can always get the latest mirror data from NodeModel. So this PR removes PreviewControl.mirrorData.

Declarations

Check these if you believe they are true

  • The code base 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.

Reviewers

@benglin : @riteshchandawar has helped to do some play testing.

@aosyatnik please help to review preview control part in case I miss something, and sorry for stealing the task from you... :-)

@ke-yu ke-yu added WIP PTAL Please Take A Look 👀 and removed WIP labels Mar 10, 2016
@ke-yu ke-yu assigned benglin and aosyatnik and unassigned benglin and aosyatnik Mar 10, 2016

return cachedValue;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Glad this is now gone, as the warning comment indicated this is a dangerous method. Wondering what's happening to the test cases that use it though... may have been removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In test cases, replace it with AssertPreviewValue(). I guess this method was added before AssertPreviewValue()? :-)

@benglin
Copy link
Contributor

benglin commented Mar 10, 2016

Hi @aosyatnik, we took this on because both @ke-yu and myself worked on the initial preview control, and us being in the same office we could discuss everything in details. Having the fix discussed, developed, and tested within hours will allow greater leeway, should anything unexpected shows up. Thanks anyway for your initial fixes!

Hey @ke-yu, few comments and LGTM, time to get a build for testing! Thanks also for helping out with this!

@benglin benglin removed the PTAL Please Take A Look 👀 label Mar 10, 2016
@kronz
Copy link
Contributor

kronz commented Mar 10, 2016

@benglin @ke-yu anything left to do here before merge?

FYI @jnealb, INCOMING!

@jnealb
Copy link
Collaborator

jnealb commented Mar 10, 2016

Ready!

@benglin benglin added the LGTM label Mar 11, 2016
ke-yu added a commit that referenced this pull request Mar 11, 2016
Fix MAGN-9568 Crash in preview control
@ke-yu ke-yu merged commit ac9dee1 into DynamoDS:master Mar 11, 2016
@ke-yu ke-yu mentioned this pull request Mar 12, 2016
@aparajit-pratap
Copy link
Contributor

@ke-yu I think we can get rid of QueryMirrorDataAsyncTask altogether now.

@ke-yu
Copy link
Contributor Author

ke-yu commented Mar 12, 2016

@aparajit-pratap sure, I forget to remove it. Will do.

@benglin benglin deleted the fix-preview-crash branch March 14, 2016 02:00
@benglin
Copy link
Contributor

benglin commented Mar 14, 2016

Good point, @aparajit-pratap! 👍

Also @ke-yu, we need this cross-merged to RC0.9.2_master branch for release testing. Thanks!

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

Labels

error/warning/crash Issues mentioning a Dynamo error, warning or crash message

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants