Represents a thread-safe OutageLog processor that will operate on each Outage with a consumer provided function on independent threads.
Inheritance: IDisposable
Esempio n. 1
0
        /// <summary>
        /// Initializes the <see cref="DataGapRecoverer"/>.
        /// </summary>
        public void Initialize()
        {
            if (m_disposed)
                throw new InvalidOperationException("Data gap recoverer has been disposed. Cannot initialize.");

            Dictionary<string, string> settings = m_connectionString.ToNonNullString().ParseKeyValuePairs();
            string setting;
            double timeInterval;
            int processingInterval;

            if (settings.TryGetValue("sourceConnectionName", out setting) && !string.IsNullOrWhiteSpace(setting))
                m_sourceConnectionName = setting;

            if (settings.TryGetValue("recoveryStartDelay", out setting) && double.TryParse(setting, out timeInterval))
                RecoveryStartDelay = timeInterval;

            if (settings.TryGetValue("dataMonitoringInterval", out setting) && double.TryParse(setting, out timeInterval))
                DataMonitoringInterval = timeInterval;

            if (settings.TryGetValue("minimumRecoverySpan", out setting) && double.TryParse(setting, out timeInterval))
                MinimumRecoverySpan = timeInterval;

            if (settings.TryGetValue("maximumRecoverySpan", out setting) && double.TryParse(setting, out timeInterval))
                MaximumRecoverySpan = timeInterval;

            if (settings.TryGetValue("filterExpression", out setting) && !string.IsNullOrWhiteSpace(setting))
                FilterExpression = setting;

            if (settings.TryGetValue("recoveryProcessingInterval", out setting) && int.TryParse(setting, out processingInterval))
                RecoveryProcessingInterval = processingInterval;

            if (settings.TryGetValue("useMillisecondResolution", out setting))
                UseMillisecondResolution = setting.ParseBoolean();

            // Get logging path, if any has been defined
            if (settings.TryGetValue("loggingPath", out setting))
            {
                setting = FilePath.GetDirectoryName(FilePath.GetAbsolutePath(setting));

                if (Directory.Exists(setting))
                    m_loggingPath = setting;
                else
                    OnStatusMessage("WARNING: Logging path \"{0}\" not found, defaulting to \"{1}\"...", setting, FilePath.GetAbsolutePath(""));
            }

            if (string.IsNullOrEmpty(m_sourceConnectionName))
                throw new NullReferenceException("Source connection name must defined - it is used to create outage log file name.");

            // Setup a new temporal data subscriber that will be used to query historical data
            m_temporalSubscription = new DataSubscriber();
            m_temporalSubscription.Name = m_sourceConnectionName + "!" + GetType().Name;
            m_temporalSubscription.DataSource = m_dataSource;
            m_temporalSubscription.ConnectionString = m_connectionString;
            m_temporalSubscription.StatusMessage += Common_StatusMessage;
            m_temporalSubscription.ProcessException += Common_ProcessException;
            m_temporalSubscription.ConnectionEstablished += TemporalSubscription_ConnectionEstablished;
            m_temporalSubscription.ConnectionTerminated += TemporalSubscription_ConnectionTerminated;
            m_temporalSubscription.ProcessingComplete += TemporalSubscription_ProcessingComplete;
            m_temporalSubscription.NewMeasurements += TemporalSubscription_NewMeasurements;
            m_temporalSubscription.Initialize();

            // Setup data gap outage log to persist unprocessed outages between class life-cycles
            m_dataGapLog = new OutageLog();
            m_dataGapLog.FileName = GetLoggingPath(m_sourceConnectionName + "_OutageLog.txt");
            m_dataGapLog.ProcessException += Common_ProcessException;
            m_dataGapLog.Initialize();

            // Setup data gap processor to process items one at a time, a 5-second minimum period is established between each gap processing
            m_dataGapLogProcessor = new OutageLogProcessor(m_dataGapLog, ProcessDataGap, CanProcessDataGap, OnProcessException, GSF.Common.Max(5000, (int)(m_recoveryStartDelay * SI.Milli)));
        }
Esempio n. 2
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="DataGapRecoverer"/> object and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        if ((object)m_dataGapRecoveryCompleted != null)
                        {
                            // Signal any waiting threads
                            m_abnormalTermination = true;
                            m_dataGapRecoveryCompleted.Set();
                            m_dataGapRecoveryCompleted.Dispose();
                            m_dataGapRecoveryCompleted = null;
                        }

                        if ((object)m_dataStreamMonitor != null)
                        {
                            m_dataStreamMonitor.Elapsed -= DataStreamMonitor_Elapsed;
                            m_dataStreamMonitor.Dispose();
                            m_dataStreamMonitor = null;
                        }

                        if ((object)m_dataGapLogProcessor != null)
                        {
                            m_dataGapLogProcessor.Dispose();
                            m_dataGapLogProcessor = null;
                        }

                        if ((object)m_dataGapLog != null)
                        {
                            m_dataGapLog.ProcessException -= Common_ProcessException;
                            m_dataGapLog.Dispose();
                            m_dataGapLog = null;
                        }

                        if ((object)m_temporalSubscription != null)
                        {
                            m_temporalSubscription.StatusMessage -= Common_StatusMessage;
                            m_temporalSubscription.ProcessException -= Common_ProcessException;
                            m_temporalSubscription.ConnectionEstablished -= TemporalSubscription_ConnectionEstablished;
                            m_temporalSubscription.ConnectionTerminated -= TemporalSubscription_ConnectionTerminated;
                            m_temporalSubscription.NewMeasurements -= TemporalSubscription_NewMeasurements;
                            m_temporalSubscription.ProcessingComplete -= TemporalSubscription_ProcessingComplete;
                            m_temporalSubscription.Dispose();
                            m_temporalSubscription = null;
                        }
                    }
                }
                finally
                {
                    m_disposed = true;  // Prevent duplicate dispose.

                    if ((object)Disposed != null)
                        Disposed(this, EventArgs.Empty);
                }
            }
        }