/// <summary> /// Adds an event to an array. If the array is full it is posted to the parent and a new array is created /// </summary> /// <param name="e"></param> private void AddToCurrentArray(NodeLoggingEvent e) { eventArray[current] = e; current++; if (current == eventArrayChunkSize) { parentNode.PostLoggingMessagesToHost(eventArray); eventArray = new NodeLoggingEvent[eventArrayChunkSize]; current = 0; } }
/// <summary> /// This function logs out all the messages currently posted to the queue. The active queue is swapped /// with the secondary queue to enable posting of messages while this function is running /// </summary> override internal bool ProcessPostedLoggingEvents() { bool processedEvents = false; lastFlushTime = DateTime.Now.Ticks; // Process all the events posted with a logger Id NodeLoggingEvent nodeLoggingEvent = null; // We may get a single event for multiple messages while ((nodeLoggingEvent = loggingQueueOfNodeEvents.Dequeue()) != null) { int loggerId = nodeLoggingEvent.LoggerId; if (loggerId != ALL_PRIVATE_EVENTSOURCES) { ErrorUtilities.VerifyThrow(eventSources.ContainsKey(loggerId), "Logger Id should be registered"); ErrorUtilities.VerifyThrow(loggerId != LOCAL_FORWARDING_EVENTSOURCE, "Should not use FWD loggers"); eventSources[loggerId].RaiseStronglyTypedEvent(nodeLoggingEvent.BuildEvent); } else { // Post event to all central loggers foreach (KeyValuePair <int, EventSource> eventSource in eventSources) { if (eventSource.Key >= FIRST_AVAILABLE_LOGGERID) { eventSource.Value.RaiseStronglyTypedEvent(nodeLoggingEvent.BuildEvent); } } } processedEvents = true; } // Process all the events in that have been already posted BuildEventArgs buildEventArgs = null; // We may get a single event for multiple messages while ((buildEventArgs = loggingQueueOfBuildEvents.Dequeue()) != null) { ProcessBuildEvent(buildEventArgs); processedEvents = true; } requestedQueueFlush = false; return(processedEvents); }
/// <summary> /// The out of proc logging service is concerned with flushing the events out to the node provider /// to be sent to the parent engine. Events which are not marked with a logger id end up being wrapped /// in a NodeLoggingEvent which was a default loggerId of 0. All events posted as BuildEventArgs fall /// into this category. Events with a loggerId need be posted as NodeLoggerEventWithLoggerId objects. /// This function is thread safe and is called both from the engine thread and communication threads to /// ensure that the events are delivered in coherent order. /// </summary> override internal bool ProcessPostedLoggingEvents() { lock (loggingQueueReadLock) { bool processedEvents = false; lastFlushTime = DateTime.Now.Ticks; // We use a local array to hold the items that will be dequeueed. We can't reuse the queues because // we give up the control of the data structure once we pass it to the node provider and we also need to maintain // order between buildEventArgs and nodeLoggingEvent. current = 0; // Process all the events in that have been already posted BuildEventArgs buildEventArgs = null; // Grab all the event args out of the queue while ((buildEventArgs = loggingQueueOfBuildEvents.Dequeue()) != null) { AddToCurrentArray(new NodeLoggingEvent(buildEventArgs)); processedEvents = true; } // Grab all the forwarded events NodeLoggingEvent nodeLoggingEvent = null; while ((nodeLoggingEvent = loggingQueueOfNodeEvents.Dequeue()) != null) { AddToCurrentArray(nodeLoggingEvent); processedEvents = true; } // If there are event - post them to the parent if (current != 0) { NodeLoggingEvent [] trimmedEventArray = new NodeLoggingEvent[current]; Array.Copy(eventArray, trimmedEventArray, current); parentNode.PostLoggingMessagesToHost(trimmedEventArray); current = 0; } requestedQueueFlush = false; return(processedEvents); } }
/// <summary> /// Called to add a logging event to the posting queue. /// </summary> /// <param name="e"></param> internal void PostLoggingEvent(NodeLoggingEvent e) { ErrorUtilities.VerifyThrowArgumentNull(e, nameof(e)); if (paused) { // Throw out the event return; } // queue the event loggingQueueOfNodeEvents.Enqueue(e); if (!requestedQueueFlush && loggingQueueOfNodeEvents.WritingQueueCount > flushQueueSize) { requestedQueueFlush = true; flushRequestEvent.Set(); } }
internal void CreateFromStream(BinaryReader reader, Hashtable loggingTypeCache) { base.CreateFromStream(reader); int numberOfNodeEvents = reader.ReadInt32(); buildEvents = new NodeLoggingEvent[numberOfNodeEvents]; for (int i = 0; i < numberOfNodeEvents; i++) { NodeLoggingEvent e; if (reader.ReadByte() == 0) { e = new NodeLoggingEvent(); } else { e = new NodeLoggingEventWithLoggerId(); } e.CreateFromStream(reader, loggingTypeCache); buildEvents[i] = e; } }
internal void PostLoggingMessagesToHost(NodeLoggingEvent[] nodeLoggingEvents) { try { parentCallback.PostLoggingMessagesToHost(nodeId, nodeLoggingEvents); } catch (Exception e) { ReportUnhandledError(e); } }
public void TestLoggingEventCustomerSerialization() { Hashtable loggingTypeCacheWrites = new Hashtable(); stream.Position = 0; BuildEventContext context = new BuildEventContext(1,3,5,7); GenericBuildEventArg genericBuildEvent = new GenericBuildEventArg("Message","Help","Sender"); genericBuildEvent.BuildEventContext = context; NodeLoggingEvent genericBuildEventLoggingEvent = new NodeLoggingEvent(genericBuildEvent); genericBuildEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); GenericCustomBuildEventArg genericCustomEvent = new GenericCustomBuildEventArg("FooFighter"); genericCustomEvent.BuildEventContext = context; NodeLoggingEvent genericCustomEventLoggingEvent = new NodeLoggingEvent(genericCustomEvent); genericCustomEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); BuildErrorEventArgs errorEvent = new BuildErrorEventArgs("Subcategory", "Code", "File", 1, 2, 3, 4, "Message", "HelpKeyword", "SenderName"); errorEvent.BuildEventContext = context; NodeLoggingEvent errorEventLoggingEvent = new NodeLoggingEvent(errorEvent); errorEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); BuildMessageEventArgs messageEvent = new BuildMessageEventArgs("Message", "HelpKeyword", "SenderName",MessageImportance.High); messageEvent.BuildEventContext = context; NodeLoggingEvent messageEventLoggingEvent = new NodeLoggingEvent(messageEvent); messageEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); BuildWarningEventArgs warningEvent = new BuildWarningEventArgs("Subcategory", "Code", "File", 1, 2, 3, 4, "Message", "HelpKeyword", "SenderName"); warningEvent.BuildEventContext = context; NodeLoggingEvent warningEventLoggingEvent = new NodeLoggingEvent(warningEvent); warningEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); ProjectStartedEventArgs projectStartedEvent = new ProjectStartedEventArgs( 8,"Message", "HelpKeyword", "ProjectFile", "TargetNames", null, null, new BuildEventContext(7,8,9,10)); projectStartedEvent.BuildEventContext = context; NodeLoggingEvent projectStartedEventLoggingEvent = new NodeLoggingEvent(projectStartedEvent); projectStartedEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); ProjectFinishedEventArgs projectFinishedEvent = new ProjectFinishedEventArgs("Message", "HelpKeyword","ProjectFile",true); projectFinishedEvent.BuildEventContext = context; NodeLoggingEvent projectFinishedEventLoggingEvent = new NodeLoggingEvent(projectFinishedEvent); projectFinishedEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); TargetStartedEventArgs targetStartedEvent = new TargetStartedEventArgs("Message", "HelpKeyword", "TargetName", "ProjectFile", "TargetFile"); targetStartedEvent.BuildEventContext = context; NodeLoggingEvent targetStartedEventLoggingEvent = new NodeLoggingEvent(targetStartedEvent); targetStartedEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); TargetFinishedEventArgs targetFinished = new TargetFinishedEventArgs("Message", "HelpKeyword","TargetName", "ProjectFile", "TargetFile", true); targetFinished.BuildEventContext = context; NodeLoggingEvent targetFinishedEventLoggingEvent = new NodeLoggingEvent(targetFinished); targetFinishedEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); TaskStartedEventArgs taskStartedEvent = new TaskStartedEventArgs("Message", "HelpKeyword", "ProjectFile", "TaskFile", "TaskName"); taskStartedEvent.BuildEventContext = context; NodeLoggingEvent taskStartedEventLoggingEvent = new NodeLoggingEvent(taskStartedEvent); taskStartedEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); TaskFinishedEventArgs taskFinishedEvent = new TaskFinishedEventArgs("Message", "HelpKeyword", "ProjectFile", "TaskFile", "TaskName", true); taskFinishedEvent.BuildEventContext = context; NodeLoggingEvent taskFinishedEventLoggingEvent = new NodeLoggingEvent(taskFinishedEvent); taskFinishedEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); BuildFinishedEventArgs buildFinishedEvent = new BuildFinishedEventArgs("Message","Help",true); buildFinishedEvent.BuildEventContext = context; NodeLoggingEvent buildFinishedEventEventLoggingEvent = new NodeLoggingEvent(buildFinishedEvent); buildFinishedEventEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); BuildStartedEventArgs buildStartedEvent = new BuildStartedEventArgs("Message","Help"); buildStartedEvent.BuildEventContext = context; NodeLoggingEvent buildStartedEventLoggingEvent = new NodeLoggingEvent(buildStartedEvent); buildStartedEventLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); TaskCommandLineEventArgs commandlineEventArg = new TaskCommandLineEventArgs("CommandLine","TaskName", MessageImportance.High); commandlineEventArg.BuildEventContext = context; NodeLoggingEvent commandlineEventArgLoggingEvent = new NodeLoggingEvent(commandlineEventArg); commandlineEventArgLoggingEvent.WriteToStream(writer, loggingTypeCacheWrites); Hashtable loggingTypeCacheReads = new Hashtable(); long streamWriteEndPosition = stream.Position; stream.Position = 0; NodeLoggingEvent nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(GenericBuildEventArg)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(GenericCustomBuildEventArg)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(BuildErrorEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(BuildMessageEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(BuildWarningEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(ProjectStartedEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(ProjectFinishedEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(TargetStartedEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(TargetFinishedEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(TaskStartedEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(TaskFinishedEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(BuildFinishedEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() == typeof(BuildStartedEventArgs)); nodeLoggingEvent = new NodeLoggingEvent(null); nodeLoggingEvent.CreateFromStream(reader, loggingTypeCacheReads); Assert.IsTrue(nodeLoggingEvent.BuildEvent.GetType() ==typeof( TaskCommandLineEventArgs)); long streamReadEndPosition = stream.Position; Assert.AreEqual(streamWriteEndPosition, streamReadEndPosition, "Expected Read and Write Positions to match"); }
/// <summary> /// Submit the logging message to the engine queue. Note that we are currently not utilizing the /// handleId, but plan to do so in the future to fill out the data structure passed to the engine /// </summary> public void PostLoggingMessagesToHost(int nodeId, NodeLoggingEvent[] nodeLoggingEventArray) { // We can safely assume that all messages need to be routed to the same engine because // they originated from the same task. This is true as long as we don't allow multiple engines within // a single process to utilize external nodes. if (nodeLoggingEventArray.Length > 0) { parentEngine.LoggingServices.PostLoggingEvents(nodeLoggingEventArray); } }
internal void CreateFromStream(BinaryReader reader, Hashtable loggingTypeCache) { base.CreateFromStream(reader); int numberOfNodeEvents = reader.ReadInt32(); buildEvents = new NodeLoggingEvent[numberOfNodeEvents]; for (int i = 0; i < numberOfNodeEvents; i++) { NodeLoggingEvent e = null; if (reader.ReadByte() == 0) { e = new NodeLoggingEvent(); } else { e = new NodeLoggingEventWithLoggerId(); } e.CreateFromStream(reader, loggingTypeCache); buildEvents[i] = e; } }
internal LocalCallDescriptorForPostLoggingMessagesToHost(NodeLoggingEvent[] buildEvents) : base(LocalCallType.PostLoggingMessagesToHost) { this.buildEvents = buildEvents; }
/// <summary> /// Called to add logging events to the posting queue. /// </summary> /// <param name="eventArray"></param> internal void PostLoggingEvents(NodeLoggingEvent[] eventArray) { ErrorUtilities.VerifyThrowArgumentNull(eventArray, "eventArray"); if (paused) { // Throw out the event return; } loggingQueueOfNodeEvents.EnqueueArray(eventArray); if (!requestedQueueFlush && loggingQueueOfNodeEvents.WritingQueueCount > flushQueueSize) { requestedQueueFlush = true; flushRequestEvent.Set(); } }
/// <summary> /// The out of proc logging service is concerned with flushing the events out to the node provider /// to be sent to the parent engine. Events which are not marked with a logger id end up being wrapped /// in a NodeLoggingEvent which was a default loggerId of 0. All events posted as BuildEventArgs fall /// into this category. Events with a loggerId need be posted as NodeLoggerEventWithLoggerId objects. /// This function is thread safe and is called both from the engine thread and communication threads to /// ensure that the events are delivered in coherent order. /// </summary> override internal bool ProcessPostedLoggingEvents() { lock (loggingQueueReadLock) { bool processedEvents = false; lastFlushTime = DateTime.Now.Ticks; // We use a local array to hold the items that will be dequeueed. We can't reuse the queues because // we give up the control of the data structure once we pass it to the node provider and we also need to maintain // order between buildEventArgs and nodeLoggingEvent. current = 0; // Process all the events in that have been already posted BuildEventArgs buildEventArgs = null; // Grab all the event args out of the queue while ((buildEventArgs = loggingQueueOfBuildEvents.Dequeue()) != null) { AddToCurrentArray(new NodeLoggingEvent(buildEventArgs)); processedEvents = true; } // Grab all the forwarded events NodeLoggingEvent nodeLoggingEvent = null; while ((nodeLoggingEvent = loggingQueueOfNodeEvents.Dequeue()) != null) { AddToCurrentArray(nodeLoggingEvent); processedEvents = true; } // If there are event - post them to the parent if (current != 0) { NodeLoggingEvent [] trimmedEventArray = new NodeLoggingEvent[current]; Array.Copy(eventArray, trimmedEventArray, current); parentNode.PostLoggingMessagesToHost(trimmedEventArray); current = 0; } requestedQueueFlush = false; return processedEvents; } }
/// <summary> /// Adds an event to an array. If the array is full it is posted to the parent and a new array is created /// </summary> /// <param name="e"></param> private void AddToCurrentArray(NodeLoggingEvent e) { eventArray[current] = e; current++; if (current == eventArrayChunkSize) { parentNode.PostLoggingMessagesToHost(eventArray); eventArray = new NodeLoggingEvent[eventArrayChunkSize]; current = 0; } }
private static LocalCallDescriptorForPostLoggingMessagesToHost CreatePostMessageCallDescriptor(int numberEvents) { NodeLoggingEvent[] eventArray = new NodeLoggingEvent[numberEvents]; for (int i = 0; i< numberEvents; i++) { BuildMessageEventArgs message = new BuildMessageEventArgs("aaaaaaaaaaaaaaa", "aaa", "a", MessageImportance.High); message.BuildEventContext = new BuildEventContext(1, 2, 3, 4); eventArray[i] = new NodeLoggingEvent(message); } LocalCallDescriptorForPostLoggingMessagesToHost LargeLogEvent = new LocalCallDescriptorForPostLoggingMessagesToHost(eventArray); return LargeLogEvent; }
/// <summary> /// Submit the logging message to the engine queue. /// </summary> public void PostLoggingMessagesToHost(int nodeProviderId, NodeLoggingEvent[] nodeLoggingEventArray) { LocalCallDescriptorForPostLoggingMessagesToHost callDescriptor = new LocalCallDescriptorForPostLoggingMessagesToHost(nodeLoggingEventArray); nodeCommandQueue.Enqueue(callDescriptor); }