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

Fix deadlock in BuildManager vs LoggingService #6837

Merged
merged 5 commits into from
Sep 15, 2021

Conversation

rokonec
Copy link
Member

@rokonec rokonec commented Sep 10, 2021

Fixes #6823

Context

There is possible deadlock in BuildManager vs LoggingService when:

  • verbosity=diagnostic or higher or /bl
  • LoggingService works in LoggerMode.Synchronous

Changes Made

LoggingService callbacks (OnProjectStarted, OnProjectFinished and OnThreadException) has been modified into async by leveraging existing workQueue.

Testing

Compiled Orchardcore in CLI and VS2022.

Notes

If these changes are considered safe, we can optionally revert PR #6717

Copy link
Member

@Forgind Forgind left a comment

Choose a reason for hiding this comment

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

Seems safe enough to me. I'm a little curious about failing cases.

// in the work queue, but the top level exception handler there should catch everything and have forwarded it to the
// OnThreadException method in this class already.
_workQueue.Complete();
Task.WaitAny(_workQueue.Completion);
Copy link
Member

Choose a reason for hiding this comment

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

Why WaitAny when you're passing only one task?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because WaitAny is only Task.WaitXX I am aware of which does not throw Exception if awaited task ends up in a Failed state. Exceptions during _workQueue DataFlow processing are handled in ProcessWorkQueue the only exceptions left this could throw, AFAIK, is OperationCanceledException which we shall swallow anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Interesting! And very unobvious. Would an explicit try/catch with a comment be more appropriate? Or at least a comment.

(Perf super nit: WaitAny takes params Task[] so the call allocates an array.)

Copy link
Member

Choose a reason for hiding this comment

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

at least a comment

Yes, please.

Copy link
Member Author

@rokonec rokonec Sep 14, 2021

Choose a reason for hiding this comment

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

I have though about it more, and it looks like it shall never throws. It will be better if that unexpected exception will surface by _workQueue.Completion.Wait();.

// in the work queue, but the top level exception handler there should catch everything and have forwarded it to the
// OnThreadException method in this class already.
_workQueue.Complete();
Task.WaitAny(_workQueue.Completion);
Copy link
Member

Choose a reason for hiding this comment

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

at least a comment

Yes, please.

@rokonec rokonec requested a review from ladipro September 14, 2021 16:47
@rokonec rokonec added the merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. label Sep 14, 2021
src/Build/BackEnd/BuildManager/BuildManager.cs Outdated Show resolved Hide resolved
@AR-May AR-May merged commit 6eb3976 into dotnet:main Sep 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Hang in EndToEndMinimumMessageImportance
5 participants