public Consumer(IAdapter adapter, Action <Exception> exceptionAction) { IActionAdapter actionAdapter = adapter as IActionAdapter; IOutputAdapter outputAdapter; Adapter = adapter; if ((object)actionAdapter != null) { Manager = new DoubleBufferedQueueManager <IMeasurement>(measurements => actionAdapter.QueueMeasurementsForProcessing(new List <IMeasurement>(measurements)), exceptionAction); } else { outputAdapter = adapter as IOutputAdapter; if ((object)outputAdapter != null) { Manager = new DoubleBufferedQueueManager <IMeasurement>(measurements => outputAdapter.QueueMeasurementsForProcessing(new List <IMeasurement>(measurements)), exceptionAction); } else { Manager = new DoubleBufferedQueueManager <IMeasurement>(() => { }); } } }
// Adds an action adapter to the dependency chain. private void AddActionAdapter(IActionAdapter adapter, ISet <IAdapter> dependencyChain, IInputAdapter[] inputAdapterCollection, IActionAdapter[] actionAdapterCollection, IOutputAdapter[] outputAdapterCollection) { HashSet <MeasurementKey> inputMeasurementKeys = new HashSet <MeasurementKey>(adapter.InputMeasurementKeys()); HashSet <MeasurementKey> outputMeasurementKeys = new HashSet <MeasurementKey>(adapter.OutputMeasurementKeys()); // Adds the adapter to the chain dependencyChain.Add(adapter); if ((object)inputAdapterCollection != null) { // Checks all input adapters to determine whether they also need to be // added to the chain as a result of this adapter being added to the chain foreach (IInputAdapter inputAdapter in inputAdapterCollection) { if (!dependencyChain.Contains(inputAdapter) && inputMeasurementKeys.Overlaps(inputAdapter.OutputMeasurementKeys())) { AddInputAdapter(inputAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } } } if ((object)actionAdapterCollection != null) { // Checks all action adapters to determine whether they also need to be // added to the chain as a result of this adapter being added to the chain foreach (IActionAdapter actionAdapter in actionAdapterCollection) { if (!dependencyChain.Contains(actionAdapter)) { if (actionAdapter.RespectInputDemands && outputMeasurementKeys.Overlaps(actionAdapter.InputMeasurementKeys())) { AddActionAdapter(actionAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } else if (actionAdapter.RespectOutputDemands && inputMeasurementKeys.Overlaps(actionAdapter.OutputMeasurementKeys())) { AddActionAdapter(actionAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } } } } if ((object)outputAdapterCollection != null) { // Checks all output adapters to determine whether they also need to be // added to the chain as a result of this adapter being added to the chain foreach (IOutputAdapter outputAdapter in outputAdapterCollection) { if (!dependencyChain.Contains(outputAdapter) && outputMeasurementKeys.Overlaps(outputAdapter.InputMeasurementKeys())) { AddOutputAdapter(outputAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } } } }
/// <summary> /// Patches the existing routing table with the supplied adapters. /// </summary> /// <param name="producerAdapters">all of the producers</param> /// <param name="consumerAdapters">all of the consumers</param> public void PatchRoutingTable(RoutingTablesAdaptersList producerAdapters, RoutingTablesAdaptersList consumerAdapters) { if (producerAdapters == null) { throw new ArgumentNullException(nameof(producerAdapters)); } if (consumerAdapters == null) { throw new ArgumentNullException(nameof(consumerAdapters)); } foreach (var producerAdapter in producerAdapters.NewAdapter) { IInputAdapter inputAdapter = producerAdapter as IInputAdapter; IActionAdapter actionAdapter = producerAdapter as IActionAdapter; if ((object)inputAdapter != null) { inputAdapter.NewMeasurements += Route; } else if ((object)actionAdapter != null) { actionAdapter.NewMeasurements += Route; } } foreach (var producerAdapter in producerAdapters.OldAdapter) { IInputAdapter inputAdapter = producerAdapter as IInputAdapter; IActionAdapter actionAdapter = producerAdapter as IActionAdapter; if ((object)inputAdapter != null) { inputAdapter.NewMeasurements -= Route; } else if ((object)actionAdapter != null) { actionAdapter.NewMeasurements -= Route; } } Dictionary <IAdapter, Consumer> consumerLookup = new Dictionary <IAdapter, Consumer>(m_globalCache.GlobalDestinationLookup); foreach (var consumerAdapter in consumerAdapters.NewAdapter) { consumerLookup.Add(consumerAdapter, new Consumer(consumerAdapter)); } foreach (var consumerAdapter in consumerAdapters.OldAdapter) { consumerLookup.Remove(consumerAdapter); } m_globalCache = new GlobalCache(consumerLookup, m_globalCache.Version + 1); RouteCount = m_globalCache.GlobalSignalLookup.Count(x => x != null); }
/// <summary> /// Releases the unmanaged resources used by the <see cref="TimestampTest"/> 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 override void Dispose(bool disposing) { if (!m_disposed) { try { if (disposing) { // Dispose timestamp service. if (m_timestampService != null) { m_timestampService.ServiceProcessException -= m_timestampService_ServiceProcessException; m_timestampService.Dispose(); } m_timestampService = null; // Dispose purge timer. if (m_purgeTimer != null) { m_purgeTimer.Elapsed -= m_purgeTimer_Elapsed; m_purgeTimer.Dispose(); } m_purgeTimer = null; // Dispose warning timer. if (m_warningTimer != null) { m_warningTimer.Elapsed -= m_warningTimer_Elapsed; m_warningTimer.Dispose(); } m_warningTimer = null; // Dispose discarding adapter. if (m_discardingAdapter != null) { m_discardingAdapter.DiscardingMeasurements -= m_discardingAdapter_DiscardingMeasurements; m_discardingAdapter.Disposed -= m_discardingAdapter_Disposed; } m_discardingAdapter = null; } } finally { m_disposed = true; // Prevent duplicate dispose. base.Dispose(disposing); // Call base class Dispose(). } } }
public LocalCache(RouteMappingHighLatencyLowCpu route, IAdapter adapter) { Enabled = true; m_route = route; IInputAdapter inputAdapter = adapter as IInputAdapter; IActionAdapter actionAdapter = adapter as IActionAdapter; if ((object)inputAdapter != null) { inputAdapter.NewMeasurements += Route; } else if ((object)actionAdapter != null) { actionAdapter.NewMeasurements += Route; } }
public LocalCache(RouteMappingDoubleBufferQueue routingTables, IAdapter producerAdapter) { m_localCacheLock = new object(); m_localSignalLookup = new Dictionary <Guid, List <Producer> >(); m_localDestinationLookup = new Dictionary <Consumer, Producer>(); m_routingTables = routingTables; IInputAdapter inputAdapter = producerAdapter as IInputAdapter; IActionAdapter actionAdapter = producerAdapter as IActionAdapter; if ((object)inputAdapter != null) { inputAdapter.NewMeasurements += Route; } else if ((object)actionAdapter != null) { actionAdapter.NewMeasurements += Route; } }
private void m_discardingAdapter_Disposed(object sender, EventArgs e) { m_discardingAdapter.DiscardingMeasurements -= m_discardingAdapter_DiscardingMeasurements; m_discardingAdapter.Disposed -= m_discardingAdapter_Disposed; m_discardingAdapter = null; }
/// <summary> /// Initializes <see cref="TimestampTest"/>. /// </summary> public override void Initialize() { base.Initialize(); string errorMessage = "{0} is missing from Settings - Example: concentratorName=TESTSTREAM"; Dictionary<string, string> settings = Settings; string setting; // Load optional parameters if (settings.TryGetValue("timeToPurge", out setting)) m_timeToPurge = Ticks.FromSeconds(double.Parse(setting)); if (settings.TryGetValue("warnInterval", out setting)) m_warnInterval = Ticks.FromSeconds(double.Parse(setting)); // Load required parameters string concentratorName; if (!settings.TryGetValue("concentratorName", out concentratorName)) throw new ArgumentException(string.Format(errorMessage, "concentratorName")); m_discardingAdapter = null; // Find the adapter whose name matches the specified concentratorName foreach (IAdapter adapter in Parent) { IActionAdapter concentrator = adapter as IActionAdapter; if (concentrator != null && string.Compare(adapter.Name, concentratorName, true) == 0) { m_discardingAdapter = concentrator; break; } } if (m_discardingAdapter == null) throw new ArgumentException(string.Format("Concentrator {0} not found.", concentratorName)); // Wait for associated adapter to initialize int timeout = m_discardingAdapter.InitializationTimeout; m_discardingAdapter.WaitForInitialize(timeout); if (!m_discardingAdapter.Initialized) throw new TimeoutException(string.Format("Timeout waiting for concentrator {0} to initialize.", concentratorName)); // Attach to adapter's discarding measurements and disposed events m_discardingAdapter.DiscardingMeasurements += m_discardingAdapter_DiscardingMeasurements; m_discardingAdapter.Disposed += m_discardingAdapter_Disposed; m_purgeTimer.Interval = m_timeToPurge.ToMilliseconds(); m_purgeTimer.Elapsed += m_purgeTimer_Elapsed; m_warningTimer.Interval = m_warnInterval.ToMilliseconds(); m_warningTimer.Elapsed += m_warningTimer_Elapsed; m_timestampService = new TimestampService(this); m_timestampService.ServiceProcessException += m_timestampService_ServiceProcessException; m_timestampService.SettingsCategory = base.Name + m_timestampService.SettingsCategory; m_timestampService.Initialize(); }
/// <summary> /// Initializes <see cref="TimestampTest"/>. /// </summary> public override void Initialize() { base.Initialize(); string errorMessage = "{0} is missing from Settings - Example: concentratorName=TESTSTREAM"; Dictionary <string, string> settings = Settings; string setting; // Load optional parameters if (settings.TryGetValue("timeToPurge", out setting)) { m_timeToPurge = Ticks.FromSeconds(double.Parse(setting)); } if (settings.TryGetValue("warnInterval", out setting)) { m_warnInterval = Ticks.FromSeconds(double.Parse(setting)); } // Load required parameters string concentratorName; if (!settings.TryGetValue("concentratorName", out concentratorName)) { throw new ArgumentException(string.Format(errorMessage, "concentratorName")); } m_discardingAdapter = null; // Find the adapter whose name matches the specified concentratorName foreach (IAdapter adapter in Parent) { IActionAdapter concentrator = adapter as IActionAdapter; if (concentrator != null && string.Compare(adapter.Name, concentratorName, true) == 0) { m_discardingAdapter = concentrator; break; } } if (m_discardingAdapter == null) { throw new ArgumentException(string.Format("Concentrator {0} not found.", concentratorName)); } // Wait for associated adapter to initialize int timeout = m_discardingAdapter.InitializationTimeout; m_discardingAdapter.WaitForInitialize(timeout); if (!m_discardingAdapter.Initialized) { throw new TimeoutException(string.Format("Timeout waiting for concentrator {0} to initialize.", concentratorName)); } // Attach to adapter's discarding measurements and disposed events m_discardingAdapter.DiscardingMeasurements += m_discardingAdapter_DiscardingMeasurements; m_discardingAdapter.Disposed += m_discardingAdapter_Disposed; m_purgeTimer.Interval = m_timeToPurge.ToMilliseconds(); m_purgeTimer.Elapsed += m_purgeTimer_Elapsed; m_warningTimer.Interval = m_warnInterval.ToMilliseconds(); m_warningTimer.Elapsed += m_warningTimer_Elapsed; m_timestampService = new TimestampService(this); m_timestampService.ServiceProcessException += m_timestampService_ServiceProcessException; m_timestampService.SettingsCategory = base.Name + m_timestampService.SettingsCategory; m_timestampService.Initialize(); }
/// <summary> /// Method for distributing new measurements in a routed fashion. /// </summary> /// <param name="newMeasurements">Collection of new measurements.</param> /// <remarks> /// Time-series framework uses this handler to directly route new measurements to the action and output adapters. /// </remarks> public virtual void RoutedMeasurementsHandler(IEnumerable <IMeasurement> newMeasurements) { if ((object)m_actionRoutes == null || (object)m_outputRoutes == null) { return; } List <IActionAdapter> actionRoutes; List <IOutputAdapter> outputRoutes; Dictionary <IActionAdapter, List <IMeasurement> > actionMeasurements = new Dictionary <IActionAdapter, List <IMeasurement> >(); Dictionary <IOutputAdapter, List <IMeasurement> > outputMeasurements = new Dictionary <IOutputAdapter, List <IMeasurement> >(); List <IMeasurement> measurements; MeasurementKey key; m_adapterRoutesCacheLock.EnterReadLock(); try { // Loop through each new measurement and look for destination routes foreach (IMeasurement measurement in newMeasurements) { key = measurement.Key; if (m_actionRoutes.TryGetValue(key, out actionRoutes)) { // Add measurements for each destination action adapter route foreach (IActionAdapter actionAdapter in actionRoutes) { if (!actionMeasurements.TryGetValue(actionAdapter, out measurements)) { measurements = new List <IMeasurement>(); actionMeasurements.Add(actionAdapter, measurements); } measurements.Add(measurement); } } if (m_outputRoutes.TryGetValue(key, out outputRoutes)) { // Add measurements for each destination output adapter route foreach (IOutputAdapter outputAdapter in outputRoutes) { if (!outputMeasurements.TryGetValue(outputAdapter, out measurements)) { measurements = new List <IMeasurement>(); outputMeasurements.Add(outputAdapter, measurements); } measurements.Add(measurement); } } } // Send broadcast action measurements foreach (IActionAdapter actionAdapter in m_actionBroadcastRoutes) { if (actionAdapter.Enabled) { actionAdapter.QueueMeasurementsForProcessing(newMeasurements); } } // Send broadcast output measurements foreach (IOutputAdapter outputAdapter in m_outputBroadcastRoutes) { if (outputAdapter.Enabled) { outputAdapter.QueueMeasurementsForProcessing(newMeasurements); } } } finally { m_adapterRoutesCacheLock.ExitReadLock(); } // Send routed action measurements foreach (KeyValuePair <IActionAdapter, List <IMeasurement> > actionAdapterMeasurements in actionMeasurements) { IActionAdapter actionAdapter = actionAdapterMeasurements.Key; if (actionAdapter.Enabled) { actionAdapter.QueueMeasurementsForProcessing(actionAdapterMeasurements.Value); } } // Send routed output measurements foreach (KeyValuePair <IOutputAdapter, List <IMeasurement> > outputAdapterMeasurements in outputMeasurements) { IOutputAdapter outputAdapter = outputAdapterMeasurements.Key; if (outputAdapter.Enabled) { outputAdapter.QueueMeasurementsForProcessing(outputAdapterMeasurements.Value); } } }
// Adds an output adapter to the dependency chain. private void AddOutputAdapter(IOutputAdapter adapter, ISet<IAdapter> dependencyChain, IInputAdapter[] inputAdapterCollection, IActionAdapter[] actionAdapterCollection, IOutputAdapter[] outputAdapterCollection) { HashSet<MeasurementKey> inputMeasurementKeys = new HashSet<MeasurementKey>(adapter.InputMeasurementKeys()); // Adds the adapter to the chain dependencyChain.Add(adapter); if ((object)inputAdapterCollection != null) { // Checks all input adapters to determine whether they also need to be // added to the chain as a result of this adapter being added to the chain foreach (IInputAdapter inputAdapter in inputAdapterCollection) { if (!dependencyChain.Contains(inputAdapter) && inputMeasurementKeys.Overlaps(inputAdapter.OutputMeasurementKeys())) AddInputAdapter(inputAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } } if ((object)actionAdapterCollection != null) { // Checks all action adapters to determine whether they also need to be // added to the chain as a result of this adapter being added to the chain foreach (IActionAdapter actionAdapter in actionAdapterCollection) { if (actionAdapter.RespectOutputDemands && !dependencyChain.Contains(actionAdapter) && inputMeasurementKeys.Overlaps(actionAdapter.OutputMeasurementKeys())) AddActionAdapter(actionAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } } }
/// <summary> /// Determines the set of adapters in the dependency chain for all adapters in the system which are either not connect or demand or are demanded. /// </summary> /// <param name="inputAdapterCollection">Collection of input adapters at start of routing table calculation.</param> /// <param name="actionAdapterCollection">Collection of action adapters at start of routing table calculation.</param> /// <param name="outputAdapterCollection">Collection of output adapters at start of routing table calculation.</param> protected virtual ISet<IAdapter> TraverseDependencyChain(IInputAdapter[] inputAdapterCollection, IActionAdapter[] actionAdapterCollection, IOutputAdapter[] outputAdapterCollection) { ISet<IAdapter> dependencyChain = new HashSet<IAdapter>(); if ((object)inputAdapterCollection != null) { foreach (IInputAdapter inputAdapter in inputAdapterCollection) { if (inputAdapter.AutoStart && !dependencyChain.Contains(inputAdapter)) AddInputAdapter(inputAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } } if ((object)actionAdapterCollection != null) { foreach (IActionAdapter actionAdapter in actionAdapterCollection) { if (actionAdapter.AutoStart && !dependencyChain.Contains(actionAdapter)) AddActionAdapter(actionAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } } if ((object)outputAdapterCollection != null) { foreach (IOutputAdapter outputAdapter in outputAdapterCollection) { if (outputAdapter.AutoStart && !dependencyChain.Contains(outputAdapter)) AddOutputAdapter(outputAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } } return dependencyChain; }
/// <summary> /// Determines the set of adapters in the dependency chain that produces the set of signals in the /// <paramref name="inputMeasurementKeysRestriction"/> and returns the set of input signals required by the /// adapters in the chain and the set of output signals produced by the adapters in the chain. /// </summary> /// <param name="inputMeasurementKeysRestriction">The set of signals that must be produced by the dependency chain.</param> /// <param name="inputAdapterCollection">Collection of input adapters at start of routing table calculation.</param> /// <param name="actionAdapterCollection">Collection of action adapters at start of routing table calculation.</param> /// <param name="outputAdapterCollection">Collection of output adapters at start of routing table calculation.</param> protected virtual ISet<IAdapter> TraverseDependencyChain(ISet<MeasurementKey> inputMeasurementKeysRestriction, IInputAdapter[] inputAdapterCollection, IActionAdapter[] actionAdapterCollection, IOutputAdapter[] outputAdapterCollection) { ISet<IAdapter> dependencyChain = new HashSet<IAdapter>(); if ((object)inputAdapterCollection != null) { foreach (IInputAdapter inputAdapter in inputAdapterCollection) { if (!dependencyChain.Contains(inputAdapter) && inputMeasurementKeysRestriction.Overlaps(inputAdapter.OutputMeasurementKeys())) AddInputAdapter(inputAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } } if ((object)actionAdapterCollection != null) { foreach (IActionAdapter actionAdapter in actionAdapterCollection) { if (!dependencyChain.Contains(actionAdapter) && inputMeasurementKeysRestriction.Overlaps(actionAdapter.OutputMeasurementKeys())) AddActionAdapter(actionAdapter, dependencyChain, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } } return dependencyChain; }
/// <summary> /// Starts or stops connect on demand adapters based on current state of demanded input or output signals. /// </summary> /// <param name="inputMeasurementKeysRestriction">The set of signals to be produced by the chain of adapters to be handled.</param> /// <param name="inputAdapterCollection">Collection of input adapters at start of routing table calculation.</param> /// <param name="actionAdapterCollection">Collection of action adapters at start of routing table calculation.</param> /// <param name="outputAdapterCollection">Collection of output adapters at start of routing table calculation.</param> /// <remarks> /// Set the <paramref name="inputMeasurementKeysRestriction"/> to null to use full adapter routing demands. /// </remarks> protected virtual void HandleConnectOnDemandAdapters(ISet<MeasurementKey> inputMeasurementKeysRestriction, IInputAdapter[] inputAdapterCollection, IActionAdapter[] actionAdapterCollection, IOutputAdapter[] outputAdapterCollection) { ISet<IAdapter> dependencyChain; ISet<MeasurementKey> inputSignals; ISet<MeasurementKey> outputSignals; ISet<MeasurementKey> requestedInputSignals; ISet<MeasurementKey> requestedOutputSignals; if (inputMeasurementKeysRestriction.Any()) { // When an input signals restriction has been defined, determine the set of adapters // by walking the dependency chain of the restriction dependencyChain = TraverseDependencyChain(inputMeasurementKeysRestriction, inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } else { // Determine the set of adapters in the dependency chain for all adapters in the system dependencyChain = TraverseDependencyChain(inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); } // Get the full set of requested input and output signals in the entire dependency chain inputSignals = new HashSet<MeasurementKey>(dependencyChain.SelectMany(adapter => adapter.InputMeasurementKeys())); outputSignals = new HashSet<MeasurementKey>(dependencyChain.SelectMany(adapter => adapter.OutputMeasurementKeys())); // Turn connect on demand input adapters on or off based on whether they are part of the dependency chain if ((object)inputAdapterCollection != null) { foreach (IInputAdapter inputAdapter in inputAdapterCollection) { if (!inputAdapter.AutoStart) { if (dependencyChain.Contains(inputAdapter)) { requestedOutputSignals = new HashSet<MeasurementKey>(inputAdapter.OutputMeasurementKeys()); requestedOutputSignals.IntersectWith(inputSignals); inputAdapter.RequestedOutputMeasurementKeys = requestedOutputSignals.ToArray(); inputAdapter.Enabled = true; } else { inputAdapter.RequestedOutputMeasurementKeys = null; inputAdapter.Enabled = false; } } } } // Turn connect on demand action adapters on or off based on whether they are part of the dependency chain if ((object)actionAdapterCollection != null) { foreach (IActionAdapter actionAdapter in actionAdapterCollection) { if (!actionAdapter.AutoStart) { if (dependencyChain.Contains(actionAdapter)) { if (actionAdapter.RespectInputDemands) { requestedInputSignals = new HashSet<MeasurementKey>(actionAdapter.InputMeasurementKeys()); requestedInputSignals.IntersectWith(outputSignals); actionAdapter.RequestedInputMeasurementKeys = requestedInputSignals.ToArray(); } if (actionAdapter.RespectOutputDemands) { requestedOutputSignals = new HashSet<MeasurementKey>(actionAdapter.OutputMeasurementKeys()); requestedOutputSignals.IntersectWith(inputSignals); actionAdapter.RequestedOutputMeasurementKeys = requestedOutputSignals.ToArray(); } actionAdapter.Enabled = true; } else { actionAdapter.RequestedInputMeasurementKeys = null; actionAdapter.RequestedOutputMeasurementKeys = null; actionAdapter.Enabled = false; } } } } // Turn connect on demand output adapters on or off based on whether they are part of the dependency chain if ((object)outputAdapterCollection != null) { foreach (IOutputAdapter outputAdapter in outputAdapterCollection) { if (!outputAdapter.AutoStart) { if (dependencyChain.Contains(outputAdapter)) { requestedInputSignals = new HashSet<MeasurementKey>(outputAdapter.OutputMeasurementKeys()); requestedInputSignals.IntersectWith(inputSignals); outputAdapter.RequestedInputMeasurementKeys = requestedInputSignals.ToArray(); outputAdapter.Enabled = true; } else { outputAdapter.RequestedInputMeasurementKeys = null; outputAdapter.Enabled = false; } } } } }