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 issue where compiler host dropped connections under load #46510

Merged
merged 11 commits into from
Aug 7, 2020

Conversation

jaredpar
Copy link
Member

@jaredpar jaredpar commented Aug 3, 2020

Under load the compiler server was failing to accept client connections faster than the client connect timeout period (one second). This lead clients to abandon the server and shell out to csc / vbc directly. This is a net negative for customers, even when the compiler server is under extreme load, because the new csc / vbc processes and the compiler server will essentially be competing for the same CPU resources. Part of the benefit of the compiler server is to avoid this competition.

The most immediate cause of this problem is that the server only creates a single NamedPipeServerStream for accepting connections and there was a significant amount of processing that had to occur between accepting one connection and creating a new NamedPipeServerStream for accepting new connections. Particularly problematic is that the work required several thread transitions. Under normal processing that was fast enough but under load that was not.

The solution here is essentially two fold:

  1. The code between accepting a new connection and creating a new listen pipe is trivial and requires no thread transitions.
  2. The server now spins up multiple NamedPipeServerStream instances in parallel to ensure that we can accept connections even when a single thread gets stalled under load.

This change also tightens the tolerance level we have in our dogfood builds for failed connections to zero. This should help us catch regressions in this area in the future.

Note: This change is best read commit by commit.

Got the API in place to make Begin / End listening a part of the
contract. This will mean the multiple servers under the hood can be
added much simpler.

Simplified the dispatching code significantly
@jaredpar jaredpar marked this pull request as ready for review August 3, 2020 17:24
@jaredpar jaredpar requested a review from a team as a code owner August 3, 2020 17:24
@jaredpar
Copy link
Member Author

jaredpar commented Aug 3, 2020

@dotnet/roslyn-compiler PTAL

@jaredpar
Copy link
Member Author

jaredpar commented Aug 5, 2020

@dotnet/roslyn-compiler PTAL

@333fred
Copy link
Member

333fred commented Aug 5, 2020

Done review pass (commit 8). Minor comments only.

@jaredpar
Copy link
Member Author

jaredpar commented Aug 6, 2020

Thanks for the feedback. Updated.

lock (servers)
{
var e = servers.GetEnumerator();
while (e.MoveNext())
Copy link
Member

@cston cston Aug 6, 2020

Choose a reason for hiding this comment

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

Could we use foreach instead? #Closed

Copy link
Member Author

@jaredpar jaredpar Aug 6, 2020

Choose a reason for hiding this comment

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

No we can't unfortunately. This is a non-generic enumeration and it's using custom properties on the enumerator to get the values. #Closed

@jaredpar
Copy link
Member Author

jaredpar commented Aug 7, 2020

The mac leg passed ... this .. this might happen. ....

@jaredpar jaredpar merged commit 72c413f into dotnet:master Aug 7, 2020
@jaredpar jaredpar deleted the faster branch August 7, 2020 21:00
@ghost ghost added this to the Next milestone Aug 7, 2020
@RikkiGibson RikkiGibson modified the milestones: Next, 16.8.P2 Aug 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants