Beispiel #1
0
 public bool Add(GrandOutputEventInfo e, FinalReceiver receiver)
 {
     if (receiver == null)
     {
         throw new ArgumentNullException();
     }
     return(DoAdd(e, receiver));
 }
Beispiel #2
0
 public EventItem( GrandOutputEventInfo e, FinalReceiver receiver )
 {
     EventInfo = e;
     Receiver = receiver;
 }
Beispiel #3
0
 bool DoAdd( GrandOutputEventInfo e, FinalReceiver receiver )
 {
     bool result = true;
     Debug.Assert( e.Entry != null || receiver == null, "Only the MustStop item has null everywhere." );
     if( receiver == null )
     {
         // This is the MustStop message.
         _queue.Enqueue( new EventItem( e, null ) );
         lock( _dispatchLock ) Monitor.Pulse( _dispatchLock );
         // Ensures that if _overloadedErrorWaiting is true, a final "Lost Event" monitoring error is sent.
         _nextCapacityError = DateTime.MinValue;
         Interlocked.MemoryBarrier();
     }
     else
     {
         // Normal message.
         Interlocked.MemoryBarrier();
         var strat = _strat;
         if( strat == null ) return false;
         if( strat.IsOpened( ref _maxQueuedCount ) )
         {
             // Normal message and no queue overload detected.
             Interlocked.Increment( ref _nonBlockingCount );
             _queue.Enqueue( new EventItem( e, receiver ) );
             lock( _dispatchLock ) Monitor.Pulse( _dispatchLock );
         }
         else
         {
             // Overload has been detected.
             // Unlock the configuration: the message will not be handled.
             if( receiver.ConfigLock != null ) receiver.ConfigLock.Unlock();
             Interlocked.Increment( ref _eventLostCount );
             // A new "Lost Event" monitoring error must be sent once.
             _overloadedErrorWaiting = true;
             result = false;
         }
         Interlocked.MemoryBarrier();
     }
     // Whatever happens, if a "Lost Event" monitoring error must be send once, 
     // checks to see if we must send it now.
     Interlocked.MemoryBarrier();
     if( _overloadedErrorWaiting )
     {
         var now = receiver != null ? e.Entry.LogTime.TimeUtc : DateTime.MaxValue;
         if( now > _nextCapacityError )
         {
             // Double check locking.
             lock( _overloadLock )
             {
                 if( _overloadedErrorWaiting && now > _nextCapacityError )
                 {
                     ActivityMonitor.CriticalErrorCollector.Add( new CKException( "GrandOutput dispatcher overload. Lost {0} total events.", _eventLostCount ), null );
                     if( receiver != null ) _nextCapacityError = now.Add( _delayBetweenCapacityError );
                     _overloadedErrorWaiting = false;
                 }
             }
         }
     }
     return result;
 }
Beispiel #4
0
 public bool Add( GrandOutputEventInfo e, FinalReceiver receiver )
 {
     if( receiver == null ) throw new ArgumentNullException();
     return DoAdd( e, receiver );
 }
Beispiel #5
0
 public EventItem(GrandOutputEventInfo e, FinalReceiver receiver)
 {
     EventInfo = e;
     Receiver  = receiver;
 }
Beispiel #6
0
        bool DoAdd(GrandOutputEventInfo e, FinalReceiver receiver)
        {
            bool result = true;

            Debug.Assert(e.Entry != null || receiver == null, "Only the MustStop item has null everywhere.");
            if (receiver == null)
            {
                // This is the MustStop message.
                _queue.Enqueue(new EventItem(e, null));
                lock (_dispatchLock) Monitor.Pulse(_dispatchLock);
                // Ensures that if _overloadedErrorWaiting is true, a final "Lost Event" monitoring error is sent.
                _nextCapacityError = DateTime.MinValue;
                Interlocked.MemoryBarrier();
            }
            else
            {
                // Normal message.
                Interlocked.MemoryBarrier();
                var strat = _strat;
                if (strat == null)
                {
                    return(false);
                }
                if (strat.IsOpened(ref _maxQueuedCount))
                {
                    // Normal message and no queue overload detected.
                    Interlocked.Increment(ref _nonBlockingCount);
                    _queue.Enqueue(new EventItem(e, receiver));
                    lock (_dispatchLock) Monitor.Pulse(_dispatchLock);
                }
                else
                {
                    // Overload has been detected.
                    // Unlock the configuration: the message will not be handled.
                    if (receiver.ConfigLock != null)
                    {
                        receiver.ConfigLock.Unlock();
                    }
                    Interlocked.Increment(ref _eventLostCount);
                    // A new "Lost Event" monitoring error must be sent once.
                    _overloadedErrorWaiting = true;
                    result = false;
                }
                Interlocked.MemoryBarrier();
            }
            // Whatever happens, if a "Lost Event" monitoring error must be send once,
            // checks to see if we must send it now.
            Interlocked.MemoryBarrier();
            if (_overloadedErrorWaiting)
            {
                var now = receiver != null ? e.Entry.LogTime.TimeUtc : DateTime.MaxValue;
                if (now > _nextCapacityError)
                {
                    // Double check locking.
                    lock ( _overloadLock )
                    {
                        if (_overloadedErrorWaiting && now > _nextCapacityError)
                        {
                            ActivityMonitor.CriticalErrorCollector.Add(new CKException("GrandOutput dispatcher overload. Lost {0} total events.", _eventLostCount), null);
                            if (receiver != null)
                            {
                                _nextCapacityError = now.Add(_delayBetweenCapacityError);
                            }
                            _overloadedErrorWaiting = false;
                        }
                    }
                }
            }
            return(result);
        }