/// <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, "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 = null; if (reader.ReadByte() == 0) { e = new NodeLoggingEvent(); } else { e = new NodeLoggingEventWithLoggerId(); } e.CreateFromStream(reader, loggingTypeCache); buildEvents[i] = e; } }