Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/Build/BackEnd/BuildManager/BuildManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,9 @@ public void BeginBuild(BuildParameters parameters)
_nodeManager.RegisterPacketHandler(NodePacketType.BuildRequestConfiguration, BuildRequestConfiguration.FactoryForDeserialization, this);
_nodeManager.RegisterPacketHandler(NodePacketType.BuildRequestConfigurationResponse, BuildRequestConfigurationResponse.FactoryForDeserialization, this);
_nodeManager.RegisterPacketHandler(NodePacketType.BuildResult, BuildResult.FactoryForDeserialization, this);
_nodeManager.RegisterPacketHandler(NodePacketType.FileAccessReport, FileAccessReport.FactoryForDeserialization, this);
_nodeManager.RegisterPacketHandler(NodePacketType.NodeShutdown, NodeShutdown.FactoryForDeserialization, this);
_nodeManager.RegisterPacketHandler(NodePacketType.ProcessReport, ProcessReport.FactoryForDeserialization, this);
_nodeManager.RegisterPacketHandler(NodePacketType.ResolveSdkRequest, SdkResolverRequest.FactoryForDeserialization, SdkResolverService as INodePacketHandler);
_nodeManager.RegisterPacketHandler(NodePacketType.ResourceRequest, ResourceRequest.FactoryForDeserialization, this);

Expand Down Expand Up @@ -1562,6 +1564,16 @@ private void ProcessPacket(int node, INodePacket packet)
HandleNodeShutdown(node, shutdownPacket);
break;

case NodePacketType.FileAccessReport:
FileAccessReport fileAccessReport = ExpectPacketType<FileAccessReport>(packet, NodePacketType.FileAccessReport);
HandleFileAccessReport(node, fileAccessReport);
break;

case NodePacketType.ProcessReport:
ProcessReport processReport = ExpectPacketType<ProcessReport>(packet, NodePacketType.ProcessReport);
HandleProcessReport(node, processReport);
break;

default:
ErrorUtilities.ThrowInternalError("Unexpected packet received by BuildManager: {0}", packet.Type);
break;
Expand Down Expand Up @@ -2463,6 +2475,22 @@ private void HandleNodeShutdown(int node, NodeShutdown shutdownPacket)
CheckForActiveNodesAndCleanUpSubmissions();
}

/// <summary>
/// Report the received <paramref name="fileAccessReport"/> to the <see cref="FileAccessManager"/>.
/// </summary>
/// <param name="nodeId">The id of the node from which the <paramref name="fileAccessReport"/> was received.</param>
/// <param name="fileAccessReport">The file access to report to the <see cref="FileAccessManager"/>.</param>
private void HandleFileAccessReport(int nodeId, FileAccessReport fileAccessReport) =>
((FileAccessManager)((IBuildComponentHost)this).GetComponent(BuildComponentType.FileAccessManager)).ReportFileAccess(fileAccessReport.FileAccessData, nodeId);

/// <summary>
/// Report the received <paramref name="processReport"/> to the <see cref="FileAccessManager"/>.
/// </summary>
/// <param name="nodeId">The id of the node from which the <paramref name="processReport"/> was received.</param>
/// <param name="processReport">The process data to report to the <see cref="FileAccessManager"/>.</param>
private void HandleProcessReport(int nodeId, ProcessReport processReport) =>
((FileAccessManager)((IBuildComponentHost)this).GetComponent(BuildComponentType.FileAccessManager)).ReportProcess(processReport.ProcessData, nodeId);

/// <summary>
/// If there are no more active nodes, cleans up any remaining submissions.
/// </summary>
Expand Down
27 changes: 27 additions & 0 deletions src/Build/BackEnd/Components/FileAccesses/FileAccessReport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Build.BackEnd;
using Microsoft.Build.Framework.FileAccess;

namespace Microsoft.Build.FileAccesses
{
internal sealed class FileAccessReport : INodePacket
{
private FileAccessData _fileAccessData;

internal FileAccessReport(FileAccessData fileAccessData) => _fileAccessData = fileAccessData;

private FileAccessReport(ITranslator translator) => Translate(translator);

/// <inheritdoc/>
public NodePacketType Type => NodePacketType.FileAccessReport;

/// <inheritdoc/>
public void Translate(ITranslator translator) => translator.Translate(ref _fileAccessData);

internal FileAccessData FileAccessData => _fileAccessData;

internal static INodePacket FactoryForDeserialization(ITranslator translator) => new FileAccessReport(translator);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,23 @@

namespace Microsoft.Build.FileAccesses
{
/// <summary>
/// Reports file accesses and process data to the in-proc node.
/// </summary>
internal sealed class OutOfProcNodeFileAccessManager : IFileAccessManager, IBuildComponent
{
public static IBuildComponent CreateComponent(BuildComponentType type)
/// <summary>
/// The <see cref="Action"/> to report file accesses and process
/// data to the in-proc node.
/// </summary>
private readonly Action<INodePacket> _sendPacket;

private OutOfProcNodeFileAccessManager(Action<INodePacket> sendPacket) => _sendPacket = sendPacket;

public static IBuildComponent CreateComponent(BuildComponentType type, Action<INodePacket> sendPacket)
{
ErrorUtilities.VerifyThrowArgumentOutOfRange(type == BuildComponentType.FileAccessManager, nameof(type));
return new OutOfProcNodeFileAccessManager();
return new OutOfProcNodeFileAccessManager(sendPacket);
}

public void InitializeComponent(IBuildComponentHost host)
Expand All @@ -25,26 +36,28 @@ public void ShutdownComponent()
{
}

public void ReportFileAccess(FileAccessData fileAccessData, int nodeId)
{
// TODO: Send the packet to the main node.
}

public void ReportProcess(ProcessData processData, int nodeId)
{
// TODO: Send the packet to the main node.
}

public FileAccessManager.HandlerRegistration RegisterHandlers(Action<BuildRequest, FileAccessData> fileAccessHandler, Action<BuildRequest, ProcessData> processHandler)
{
// This method should not be called in OOP nodes
/// <summary>
/// Reports a file access to the in-proc node.
/// </summary>
/// <param name="fileAccessData">The file access to report to the in-proc node.</param>
/// <param name="nodeId">The id of the reporting out-of-proc node.</param>
public void ReportFileAccess(FileAccessData fileAccessData, int nodeId) => _sendPacket(new FileAccessReport(fileAccessData));

/// <summary>
/// Reports process data to the in-proc node.
/// </summary>
/// <param name="processData">The process data to report to the in-proc node.</param>
/// <param name="nodeId">The id of the reporting out-of-proc node.</param>
public void ReportProcess(ProcessData processData, int nodeId) => _sendPacket(new ProcessReport(processData));

// This method should not be called in OOP nodes.
public FileAccessManager.HandlerRegistration RegisterHandlers(
Action<BuildRequest, FileAccessData> fileAccessHandler,
Action<BuildRequest, ProcessData> processHandler) =>
throw new NotImplementedException();
}

public void WaitForFileAccessReportCompletion(int globalRequestId, CancellationToken cancellationToken)
{
// This method should not be called in OOP nodes
// This method should not be called in OOP nodes.
public void WaitForFileAccessReportCompletion(int globalRequestId, CancellationToken cancellationToken) =>
throw new NotImplementedException();
}
}
}
27 changes: 27 additions & 0 deletions src/Build/BackEnd/Components/FileAccesses/ProcessReport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Build.BackEnd;
using Microsoft.Build.Framework.FileAccess;

namespace Microsoft.Build.FileAccesses
{
internal sealed class ProcessReport : INodePacket
{
private ProcessData _processData;

internal ProcessReport(ProcessData processData) => _processData = processData;

private ProcessReport(ITranslator translator) => Translate(translator);

/// <inheritdoc/>
public NodePacketType Type => NodePacketType.ProcessReport;

internal ProcessData ProcessData => _processData;

internal static INodePacket FactoryForDeserialization(ITranslator translator) => new ProcessReport(translator);

/// <inheritdoc/>
public void Translate(ITranslator translator) => translator.Translate(ref _processData);
}
}
6 changes: 3 additions & 3 deletions src/Build/BackEnd/Node/OutOfProcNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@ public OutOfProcNode()
// Create a factory for the out-of-proc SDK resolver service which can pass our SendPacket delegate to be used for sending packets to the main node
OutOfProcNodeSdkResolverServiceFactory sdkResolverServiceFactory = new OutOfProcNodeSdkResolverServiceFactory(SendPacket);
((IBuildComponentHost)this).RegisterFactory(BuildComponentType.SdkResolverService, sdkResolverServiceFactory.CreateInstance);

((IBuildComponentHost)this).RegisterFactory(BuildComponentType.FileAccessManager, OutOfProcNodeFileAccessManager.CreateComponent);

_sdkResolverService = (this as IBuildComponentHost).GetComponent(BuildComponentType.SdkResolverService) as ISdkResolverService;
((IBuildComponentHost)this).RegisterFactory(
BuildComponentType.FileAccessManager,
(componentType) => OutOfProcNodeFileAccessManager.CreateComponent(componentType, SendPacket));

if (s_projectRootElementCacheBase == null)
{
Expand Down
6 changes: 4 additions & 2 deletions src/Build/Microsoft.Build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,11 @@
<Compile Include="BackEnd\Components\ProjectCache\*.cs" />
<Compile Include="BackEnd\Components\Communications\CurrentHost.cs" />
<Compile Include="BackEnd\Components\Communications\ServerNodeEndpointOutOfProc.cs" />
<Compile Include="BackEnd\Components\FileAccesses\OutOfProcNodeFileAccessManager.cs" />
<Compile Include="BackEnd\Components\FileAccesses\FileAccessManager.cs" />
<Compile Include="BackEnd\Components\FileAccesses\IFileAccessManager.cs" />
<Compile Include="BackEnd\Components\FileAccesses\FileAccessManager.cs" />
<Compile Include="BackEnd\Components\FileAccesses\FileAccessReport.cs" />
<Compile Include="BackEnd\Components\FileAccesses\OutOfProcNodeFileAccessManager.cs" />
<Compile Include="BackEnd\Components\FileAccesses\ProcessReport.cs" />
<Compile Include="BackEnd\Components\RequestBuilder\AssemblyLoadsTracker.cs" />
<Compile Include="BackEnd\Components\SdkResolution\SdkResolverException.cs" />
<Compile Include="BackEnd\Components\SdkResolution\TranslationHelpers.cs" />
Expand Down
158 changes: 105 additions & 53 deletions src/Shared/BinaryTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,41 @@ public void Translate(ref BuildEventContext value)
_reader.ReadInt32());
}

/// <inheritdoc/>
public void Translate(ref FileAccessData fileAccessData)
{
ReportedFileOperation reportedFileOperation = default;
RequestedAccess requestedAccess = default;
uint processId = default;
uint error = default;
DesiredAccess desiredAccess = default;
FlagsAndAttributes flagsAndAttributes = default;
string path = default;
#nullable enable
string? processArgs = default;
#nullable disable
bool isAnAugmentedFileAccess = default;
TranslateEnum(ref reportedFileOperation, (int)reportedFileOperation);
TranslateEnum(ref requestedAccess, (int)requestedAccess);
Translate(ref processId);
Translate(ref error);
TranslateEnum(ref desiredAccess, (int)desiredAccess);
TranslateEnum(ref flagsAndAttributes, (int)flagsAndAttributes);
Translate(ref path);
Translate(ref processArgs);
Translate(ref isAnAugmentedFileAccess);
fileAccessData = new FileAccessData(
reportedFileOperation,
requestedAccess,
processId,
error,
desiredAccess,
flagsAndAttributes,
path,
processArgs,
isAnAugmentedFileAccess);
}

/// <inheritdoc/>
public void Translate(ref List<FileAccessData> fileAccessDataList)
{
Expand All @@ -416,38 +451,35 @@ public void Translate(ref List<FileAccessData> fileAccessDataList)
fileAccessDataList = new List<FileAccessData>(count);
for (int i = 0; i < count; i++)
{
ReportedFileOperation reportedFileOperation = default;
RequestedAccess requestedAccess = default;
uint processId = default;
uint error = default;
DesiredAccess desiredAccess = default;
FlagsAndAttributes flagsAndAttributes = default;
string path = default;
#nullable enable
string? processArgs = default;
#nullable disable
bool isAnAugmentedFileAccess = default;
TranslateEnum(ref reportedFileOperation, (int)reportedFileOperation);
TranslateEnum(ref requestedAccess, (int)requestedAccess);
Translate(ref processId);
Translate(ref error);
TranslateEnum(ref desiredAccess, (int)desiredAccess);
TranslateEnum(ref flagsAndAttributes, (int)flagsAndAttributes);
Translate(ref path);
Translate(ref processArgs);
Translate(ref isAnAugmentedFileAccess);
fileAccessDataList.Add(new FileAccessData(
reportedFileOperation,
requestedAccess,
processId,
error,
desiredAccess,
flagsAndAttributes,
path,
processArgs,
isAnAugmentedFileAccess));
FileAccessData fileAccessData = default;
Translate(ref fileAccessData);
fileAccessDataList.Add(fileAccessData);
}
}

/// <inheritdoc/>
public void Translate(ref ProcessData processData)
{
string processName = default;
uint processId = default;
uint parentProcessId = default;
DateTime creationDateTime = default;
DateTime exitDateTime = default;
uint exitCode = default;
Translate(ref processName);
Translate(ref processId);
Translate(ref parentProcessId);
Translate(ref creationDateTime);
Translate(ref exitDateTime);
Translate(ref exitCode);
processData = new ProcessData(
processName,
processId,
parentProcessId,
creationDateTime,
exitDateTime,
exitCode);
}
#endif

/// <summary>
Expand Down Expand Up @@ -1108,6 +1140,31 @@ public void Translate(ref BuildEventContext value)
_writer.Write(value.TaskId);
}

/// <inheritdoc/>
public void Translate(ref FileAccessData fileAccessData)
{
ReportedFileOperation reportedFileOperation = fileAccessData.Operation;
RequestedAccess requestedAccess = fileAccessData.RequestedAccess;
uint processId = fileAccessData.ProcessId;
uint error = fileAccessData.Error;
DesiredAccess desiredAccess = fileAccessData.DesiredAccess;
FlagsAndAttributes flagsAndAttributes = fileAccessData.FlagsAndAttributes;
string path = fileAccessData.Path;
#nullable enable
string? processArgs = fileAccessData.ProcessArgs;
#nullable disable
bool isAnAugmentedFileAccess = fileAccessData.IsAnAugmentedFileAccess;
TranslateEnum(ref reportedFileOperation, (int)reportedFileOperation);
TranslateEnum(ref requestedAccess, (int)requestedAccess);
Translate(ref processId);
Translate(ref error);
TranslateEnum(ref desiredAccess, (int)desiredAccess);
TranslateEnum(ref flagsAndAttributes, (int)flagsAndAttributes);
Translate(ref path);
Translate(ref processArgs);
Translate(ref isAnAugmentedFileAccess);
}

/// <inheritdoc/>
public void Translate(ref List<FileAccessData> fileAccessDataList)
{
Expand All @@ -1118,29 +1175,24 @@ public void Translate(ref List<FileAccessData> fileAccessDataList)

int count = fileAccessDataList.Count;
Translate(ref count);
fileAccessDataList.ForEach(fileAccessData =>
{
ReportedFileOperation reportedFileOperation = fileAccessData.Operation;
RequestedAccess requestedAccess = fileAccessData.RequestedAccess;
uint processId = fileAccessData.ProcessId;
uint error = fileAccessData.Error;
DesiredAccess desiredAccess = fileAccessData.DesiredAccess;
FlagsAndAttributes flagsAndAttributes = fileAccessData.FlagsAndAttributes;
string path = fileAccessData.Path;
#nullable enable
string? processArgs = fileAccessData.ProcessArgs;
#nullable disable
bool isAnAugmentedFileAccess = fileAccessData.IsAnAugmentedFileAccess;
TranslateEnum(ref reportedFileOperation, (int)reportedFileOperation);
TranslateEnum(ref requestedAccess, (int)requestedAccess);
Translate(ref processId);
Translate(ref error);
TranslateEnum(ref desiredAccess, (int)desiredAccess);
TranslateEnum(ref flagsAndAttributes, (int)flagsAndAttributes);
Translate(ref path);
Translate(ref processArgs);
Translate(ref isAnAugmentedFileAccess);
});
fileAccessDataList.ForEach(fileAccessData => Translate(ref fileAccessData));
}

/// <inheritdoc/>
public void Translate(ref ProcessData processData)
{
string processName = processData.ProcessName;
uint processId = processData.ProcessId;
uint parentProcessId = processData.ParentProcessId;
DateTime creationDateTime = processData.CreationDateTime;
DateTime exitDateTime = processData.ExitDateTime;
uint exitCode = processData.ExitCode;
Translate(ref processName);
Translate(ref processId);
Translate(ref parentProcessId);
Translate(ref creationDateTime);
Translate(ref exitDateTime);
Translate(ref exitCode);
}
#endif

Expand Down
Loading