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

[WIP] async code and dispose in tests #14649

Closed
wants to merge 15 commits into from
Closed

Conversation

pinzart90
Copy link
Contributor

@pinzart90 pinzart90 commented Nov 28, 2023

Issues:

  1. Deadlock in Md2html during tests (could happen live too).
    GetData().Result will block the current thread. Inside GetData we have an await which will cause the main thread to poll for the status of the awaited task
  2. DocumentationBrowserView.NavigateToPage can sometimes be called from non UI thread and causes exceptions to be thrown when accessing UI components.
  3. Exception The calling thread cannot access this object because a different thread owns it or something even weirder.
    UI tests were running on the threadpool sync context. This means that any async operation could be scheduled on the
    threadpool. This can cause issues/exceptions with UI controls (like webview2)
  4. System.ObjectDisposedException: Cannot access a disposed object or something even weirder . UI tests can finish faster that async operations can execute. This means that a UI control could get disposed even if internal async operations have not finished yet

@@ -48,7 +49,7 @@ public void UpdateNotificationWindowSize(int height)
}
}

public class NotificationCenterController
public class NotificationCenterController : IDisposable
Copy link
Contributor Author

Choose a reason for hiding this comment

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

made this class disposable so we can clean up when the parent view extension is Disposed.

@@ -104,7 +102,7 @@ internal string SanitizeHtml(string content)

var output = GetData(processCommunicationTimeoutms);

return output.Result;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This caused a deadlock when running tests on a single thread (could happen in live scenario too)
The .Result blocks the current thread until the task is completed.
And inside the GetData() the await Task will never finish because the main thread cannot poll for the status

Copy link
Member

Choose a reason for hiding this comment

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

would an alternative be to always access this data from another thread, for example - like we do with the feature flags manager startup - run the GetData call inside on a task in the thread pool?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It might work. But having a separate thread started everywhere GetData.Result is called might be harder to maintain
I find it easier to reason about when the entire concurrency logic is boxed up inside the GetData method so callers do not need to worry about how to call it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually used the approach you suggested for another case (in a test file)
https://github.com/DynamoDS/Dynamo/pull/14649/files#diff-be236d5cf3315a8f37d3d67a4adb628825430289b534dbd620952c47f2d286b0R1136
For production code (like GetData) I still think it would make it tricky to figure out how to use it safely.

@pinzart90 pinzart90 closed this Dec 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants