Skip to content

Conversation

@AR-May
Copy link
Member

@AR-May AR-May commented May 18, 2022

Fixes #7315.

Context

Adding an opt-in feature for executing the build in MSBuild server. With this feature turned on, MSBuild sends the build request for execution to the MSBuild server node. This approach avoids to execute targets and tasks into a short-living process from CLI tools like .NET SDK and MSBuild.exe.

Changes Made

This PR implements:

  • a new node that accepts build request from client. This approach avoids spawning a new MSBuild process for every build from CLI tools like .NET SDK.
  • a new MSBuild client classes able to communicate with MSBuild server node via the named pipe.
  • unit tests for the new code path (TODO).

MichalPavlik and others added 6 commits April 21, 2022 14:24
Fixes #7374, #7373

Context
MSBuild client is a new code path that is triggered with opt-in env variable. It sends the build request for execution to the MSBuild server node. This approach avoids to do execute targets and tasks into a short-living process from CLI tools like .NET SDK and MSBuild.exe.

Changes Made
This PR implements a new MSBuild client classes able to communicate with MSBuild server node via the named pipe.

Testing
Manually tested. Automatic tests will be added in another PR.

Co-authored-by: Forgind <Forgind@users.noreply.github.com>
Co-authored-by: Roman Konecny <rokonecn@microsoft.com>
* Some instrumentation

* Add more details to ETW

* Use class-wide variables
Copy link

@donJoseLuis donJoseLuis left a comment

Choose a reason for hiding this comment

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

my review's timebox expired. Please take a look at my comments, I only managed to review 5/28 files.

* Added cancelation feature
Copy link
Contributor

@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.

Just need to review OutOfProcServerNode

Forgind and others added 12 commits May 30, 2022 16:17
* Fix control sequence emission
* Some cleanup
Co-authored-by: Forgind <Forgind@users.noreply.github.com>
…he (#7655)

* Solving memory leak by reusing BuildManager and ProjectRoolElementCache
* Do not clear project root element cache if in auto reload.
* Add giant test for MSBuild Server
* Add comm traces
* Remove test that uses MSBUILDNOINPROCNODE flag: it checks the wrong behavior.
* Add comments about WaitForExit and set a timeout for the process execution.

Co-authored-by: AR-May <67507805+AR-May@users.noreply.github.com>
Co-authored-by: Roman Konecny <rokonecn@microsoft.com>
* Added cancellation support for client.

* Added cancellation support for client.

* Fixing wrong merge

* Removed "Cancelled" exit type

* Resolving comments
* Handle race condition
* Clean running server nodes in tests.
rokonec and others added 3 commits June 20, 2022 19:04
Fixes #7658

Context
See #7658

Changes Made
MSBuild Server clients detects: ConsoleBufferWidth, AcceptAnsiColorCodes, ConsoleIsScreen, ConsoleBackgroundColor of current console and sent it to Server in ServerNodeBuildCommand.
Server overrides ConsoleConfigueation so our loggers can get target console configuration.

Testing
Manual

Notes
There are no expected functional changes for NON Server and hence also VS scenarios.

Co-authored-by: Forgind <Forgind@users.noreply.github.com>
Co-authored-by: AR-May <67507805+AR-May@users.noreply.github.com>
* Send command line as string[] in dotnet builds.
MichalPavlik and others added 3 commits June 30, 2022 10:06
* Fixed some commented issues
* Update doc

* Fixed typo

* Fixed another typo

* Update documentation/MSBuild-Server.md

Co-authored-by: Forgind <Forgind@users.noreply.github.com>

* Update documentation/MSBuild-Server.md

Co-authored-by: Forgind <Forgind@users.noreply.github.com>

* Update documentation/MSBuild-Server.md

Co-authored-by: Forgind <Forgind@users.noreply.github.com>

* Update documentation/MSBuild-Server.md

Co-authored-by: Forgind <Forgind@users.noreply.github.com>

* Update documentation/MSBuild-Server.md

Co-authored-by: Forgind <Forgind@users.noreply.github.com>

* Update documentation/MSBuild-Server.md

Co-authored-by: Forgind <Forgind@users.noreply.github.com>

* Resolving comments

Co-authored-by: Forgind <Forgind@users.noreply.github.com>
@benvillalobos benvillalobos added the Area: Engine Issues impacting the core execution of targets and tasks. label Jul 5, 2022
@rainersigwald
Copy link
Member

Notes from call with @rokonec going over the headlines on this:

  • Looked at MSBuild node stuff and some VBCSCompiler as-a-service stuff
    • Mostly already reviewed
  • Some commands that get serialized
  • more complex stuff around console capture + serialization
    • batched or 100ms timer
    • could maybe test per-line/write to console
  • Commit about memory leak (don't dispose BuildManager in server mode)
  • Check ProjectRootElementCache if autoreload
  • complex stuff: console properties/redirection status has to be passed in build request, set where possible or stored in a static object instead of Console object itself <-- could be surprising if a logger checks this stuff
  • PrepareConsoleColor to use VT100 most of the time
  • (self) think about compat with new console logger project
  • (self) we should turn this on in the second-stage build

@rokonec rokonec requested review from Forgind and donJoseLuis July 13, 2022 13:48
Copy link
Contributor

@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.

🚢

processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
processStartInfo.CreateNoWindow = (creationFlags | BackendNativeMethods.CREATENOWINDOW) == BackendNativeMethods.CREATENOWINDOW;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
processStartInfo.CreateNoWindow = (creationFlags | BackendNativeMethods.CREATENOWINDOW) == BackendNativeMethods.CREATENOWINDOW;
processStartInfo.CreateNoWindow = (creationFlags & BackendNativeMethods.CREATENOWINDOW) == BackendNativeMethods.CREATENOWINDOW;

?

/// </summary>
internal sealed class ServerNodeBuildCommand : INodePacket
{
private string _commandLine = default!;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer just disabling nullable here if that's viable, but it isn't critical.

{
Console.CancelKeyPress += Console_CancelKeyPress;

DebuggerLaunchCheck();
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm unsure if it's better to break into the client or just wait to break into the server...it's useful to be able to debug anything that might be going wrong, but server was supposed to be mostly invisible, and that'd be visible.


// Now write in the actual packet length
memoryStream.Position = 1;
_binaryWriter.Write(packetStreamLength - 5);
Copy link
Contributor

Choose a reason for hiding this comment

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

Where did 5 come from?

Copy link
Member

Choose a reason for hiding this comment

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

this code was inspired by NodeEndpointOutOfProcBase.RunReadLoop and has meaning of size of header (byte: packet type, int32: sizeInBytes).


public class TransientTestProcess : TransientTestState
{
private readonly int _processId;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: process IDs can be reused, so it'd be better to keep a Process object (which internally keeps an OS handle open so that the PID can't be reused until the Process object is cleaned up).

Comment on lines +25 to +54
public class SleepingTask : Microsoft.Build.Utilities.Task
{
public int SleepTime { get; set; }

/// <summary>
/// Sleep for SleepTime milliseconds.
/// </summary>
/// <returns>Success on success.</returns>
public override bool Execute()
{
Thread.Sleep(SleepTime);
return !Log.HasLoggedErrors;
}
}

public class ProcessIdTask : Microsoft.Build.Utilities.Task
{
[Output]
public int Pid { get; set; }

/// <summary>
/// Log the id for this process.
/// </summary>
/// <returns></returns>
public override bool Execute()
{
Pid = Process.GetCurrentProcess().Id;
return true;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

I think we have both of these in some test assembly somewhere, but they're tiny so reimplementing is probably ok.

{
try
{
IntPtr stdOut = NativeMethodsShared.GetStdHandle(NativeMethodsShared.STD_OUTPUT_HANDLE);
Copy link
Member

Choose a reason for hiding this comment

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

TIL this is a handle you're not supposed to dispose: https://docs.microsoft.com/en-us/windows/console/getstdhandle#handle-disposal

@Forgind Forgind merged commit 1887d29 into main Jul 13, 2022
@Forgind Forgind deleted the feature/msbuild-server branch July 13, 2022 19:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Engine Issues impacting the core execution of targets and tasks. Area: Performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MSBUILD Server

9 participants