Esempio n. 1
0
        /// <summary>
        /// When error=null => error cleared. When msg==null => exceptions surfaced from DoPulse()
        /// </summary>
        internal void FailoverDestination(Sink sink, Exception error, Message msg)
        {
            if (m_NestedFailureCount >= MAX_NESTED_FAILURES)
            {
                return;                                             //stop cascade recursion
            }
            m_NestedFailureCount++;
            try
            {
                if (error == null)    //error lifted
                {
                    if (sink == m_FailoverErrorSink)
                    {
                        m_FailoverErrorSink = null;
                        m_FailoverError     = null;
                    }
                    return;
                }

                if (msg == null)
                {
                    return;                  //i.e. OnPulse()
                }
                var failoverName = sink.Failover;
                if (string.IsNullOrEmpty(failoverName))
                {
                    failoverName = this.DefaultFailover;
                }
                if (string.IsNullOrEmpty(failoverName))
                {
                    return;                                           //nowhere to failover
                }
                Sink failover = null;
                lock (m_Sinks)
                    failover = m_Sinks.FirstOrDefault(d => string.Equals(d.Name, failoverName, StringComparison.InvariantCultureIgnoreCase));


                if (failover == null)
                {
                    return;
                }

                if (failover == sink)
                {
                    return;                      //circular reference, cant fail into destination that failed
                }
                try
                {
                    failover.SendRegularAndFailures(msg);

                    if (sink.GenerateFailoverMessages || failover.GenerateFailoverMessages)
                    {
                        var emsg = new Message();
                        emsg.Type  = MessageType.Error;
                        emsg.From  = sink.Name;
                        emsg.Topic = CoreConsts.LOG_TOPIC;
                        emsg.Text  = string.Format(
                            StringConsts.LOGSVC_FAILOVER_MSG_TEXT,
                            msg.Guid,
                            sink.Name,
                            failover.Name,
                            sink.AverageProcessingTimeMs);
                        emsg.RelatedTo = msg.Guid;
                        emsg.Exception = error;


                        failover.SendRegularAndFailures(emsg);
                    }

                    failover.DoPulse();
                }
                catch (Exception failoverError)
                {
                    m_FailoverErrorSink = failover;
                    m_FailoverError     = failoverError;
                }
            }
            finally
            {
                m_NestedFailureCount--;
            }
        }