From f9a16364e57b14b8ba1360bc73e3b8d62b5b0904 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Fri, 3 Aug 2018 15:58:02 -0700 Subject: [PATCH] Always throttle log message handling Fixes #3577 by applying the throttling policy to the processing of all logging events, not just those from other nodes. While this will slow the build down, it will keep the memory usage of log events in the to-be-processed queue bounded, preventing the OOM reported in the bug. --- .../BackEnd/LoggingServicesLogMethod_Tests.cs | 2 +- .../BackEnd/Components/Logging/LoggingService.cs | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/Build.UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs b/src/Build.UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs index d81f4dcdbb5..13e14d64a35 100644 --- a/src/Build.UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs +++ b/src/Build.UnitTests/BackEnd/LoggingServicesLogMethod_Tests.cs @@ -1772,7 +1772,7 @@ public static IBuildComponent CreateLoggingService(LoggerMode mode, int nodeId, /// Override the method to log which event was processed so it can be verified in a test /// /// Build event which was asked to be processed - internal override void ProcessLoggingEvent(object buildEvent, bool allowThrottling = false) + internal override void ProcessLoggingEvent(object buildEvent) { if (buildEvent is BuildEventArgs) { diff --git a/src/Build/BackEnd/Components/Logging/LoggingService.cs b/src/Build/BackEnd/Components/Logging/LoggingService.cs index 9b41c0ede75..a56a8cdfed7 100644 --- a/src/Build/BackEnd/Components/Logging/LoggingService.cs +++ b/src/Build/BackEnd/Components/Logging/LoggingService.cs @@ -786,7 +786,7 @@ public void PacketReceived(int node, INodePacket packet) LogMessagePacket loggingPacket = (LogMessagePacket)packet; InjectNonSerializedData(loggingPacket); - ProcessLoggingEvent(loggingPacket.NodeBuildEvent, allowThrottling: true); + ProcessLoggingEvent(loggingPacket.NodeBuildEvent); } /// @@ -1060,24 +1060,19 @@ public void LogBuildEvent(BuildEventArgs buildEvent) /// This method will becalled from multiple threads in asynchronous mode. /// /// Determine where to send the buildevent either to the filters or to a specific sink. - /// When in Asynchronous mode the event should to into the logging queue (as long as we are initialized). + /// When in Asynchronous mode the event should go into the logging queue (as long as we are initialized). /// In Synchronous mode the event should be routed to the correct sink or logger right away /// /// BuildEventArgs to process - /// true to allow throttling, otherwise false. /// buildEvent is null - internal virtual void ProcessLoggingEvent(object buildEvent, bool allowThrottling = false) + internal virtual void ProcessLoggingEvent(object buildEvent) { ErrorUtilities.VerifyThrow(buildEvent != null, "buildEvent is null"); if (_logMode == LoggerMode.Asynchronous) { // If the queue is at capacity, this call will block - the task returned by SendAsync only completes // when the message is actually consumed or rejected (permanently) by the buffer. - var task = _loggingQueue.SendAsync(buildEvent); - if (allowThrottling) - { - task.Wait(); - } + _loggingQueue.SendAsync(buildEvent).Wait(); } else {