private void ProcessDataGap(Outage dataGap)
{
// Establish start and stop time for temporal session
m_subscriptionInfo.StartTime = dataGap.Start.ToString(OutageLog.DateTimeFormat, CultureInfo.InvariantCulture);
m_subscriptionInfo.StopTime = dataGap.End.ToString(OutageLog.DateTimeFormat, CultureInfo.InvariantCulture);
OnStatusMessage(MessageLevel.Info, $"Starting data gap recovery for period \"{m_subscriptionInfo.StartTime}\" - \"{m_subscriptionInfo.StopTime}\"...");
// Enable data monitor
m_dataStreamMonitor.Enabled = true;
// Reset measurement counters
m_measurementsRecoveredForDataGap = 0;
m_measurementsRecoveredOverLastInterval = 0;
// Reset processing fields
m_mostRecentRecoveredTime = dataGap.Start.Ticks;
m_abnormalTermination = false;
// Reset process completion wait handle
m_dataGapRecoveryCompleted.Reset();
// Start temporal data recovery session
m_temporalSubscription.Subscribe(m_subscriptionInfo);
// Wait for process completion - success or fail
m_dataGapRecoveryCompleted.Wait();
// If temporal session failed to connect, retry data recovery for this outage
if (m_abnormalTermination)
{
// Make sure any data recovered so far doesn't get unnecessarily re-recovered, this requires that source historian report data in time-sorted order
dataGap = new Outage(new DateTime(GSF.Common.Max((Ticks)dataGap.Start.Ticks, m_mostRecentRecoveredTime - (m_subscriptionInfo.UseMillisecondResolution ? Ticks.PerMillisecond : 1L)), DateTimeKind.Utc), dataGap.End);
// Re-insert adjusted data gap at the top of the processing queue
m_dataGapLog.Insert(0, dataGap);
FlushLogAsync();
if (m_measurementsRecoveredForDataGap == 0)
OnStatusMessage(MessageLevel.Warning, $"Failed to establish temporal session. Data recovery for period \"{m_subscriptionInfo.StartTime}\" - \"{m_subscriptionInfo.StopTime}\" will be re-attempted.");
else
OnStatusMessage(MessageLevel.Warning, $"Temporal session was disconnected during recovery operation. Data recovery for adjusted period \"{dataGap.Start.ToString(OutageLog.DateTimeFormat, CultureInfo.InvariantCulture)}\" - \"{m_subscriptionInfo.StopTime}\" will be re-attempted.");
}
// Unsubscribe from temporal session
m_temporalSubscription.Unsubscribe();
// Disable data monitor
m_dataStreamMonitor.Enabled = false;
OnStatusMessage(m_measurementsRecoveredForDataGap == 0 ? MessageLevel.Warning : MessageLevel.Info, $"Recovered {m_measurementsRecoveredForDataGap} measurements for period \"{m_subscriptionInfo.StartTime}\" - \"{m_subscriptionInfo.StopTime}\".");
}