/// <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)); } // Attach to NewMeasurements event of all producer adapters that are new foreach (IAdapter producerAdapter in producerAdapters.NewAdapter) { new LocalCache(this, producerAdapter); } Dictionary <IAdapter, Consumer> consumerLookup = new Dictionary <IAdapter, Consumer>(m_globalCache.GlobalDestinationLookup); // Create new consumer adapters foreach (var consumerAdapter in consumerAdapters.NewAdapter) { consumerLookup.Add(consumerAdapter, new Consumer(consumerAdapter, m_onProcessException)); } // Remove old adapters foreach (var consumerAdapter in consumerAdapters.OldAdapter) { consumerLookup.Remove(consumerAdapter); } Interlocked.Exchange(ref m_globalCache, new GlobalCache(consumerLookup, m_globalCache.Version + 1)); }
/// <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> /// 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) { m_producerLookup.Add(producerAdapter, new LocalCache(this, producerAdapter)); } foreach (var producerAdapter in producerAdapters.OldAdapter) { m_producerLookup[producerAdapter].Enabled = false; m_producerLookup.Remove(producerAdapter); } 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); }
/// <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)); // Attach to NewMeasurements event of all producer adapters that are new foreach (IAdapter producerAdapter in producerAdapters.NewAdapter) { new LocalCache(this, producerAdapter); } Dictionary<IAdapter, Consumer> consumerLookup = new Dictionary<IAdapter, Consumer>(m_globalCache.GlobalDestinationLookup); // Create new consumer adapters foreach (var consumerAdapter in consumerAdapters.NewAdapter) { consumerLookup.Add(consumerAdapter, new Consumer(consumerAdapter, m_onProcessException)); } // Remove old adapters foreach (var consumerAdapter in consumerAdapters.OldAdapter) { consumerLookup.Remove(consumerAdapter); } Interlocked.Exchange(ref m_globalCache, new GlobalCache(consumerLookup, m_globalCache.Version + 1)); }
private void CalculateRoutingTables() { long startTime = DateTime.UtcNow.Ticks; Time elapsedTime; IInputAdapter[] inputAdapterCollection = null; IActionAdapter[] actionAdapterCollection = null; IOutputAdapter[] outputAdapterCollection = null; bool retry = true; OnStatusMessage("Starting measurement route calculation..."); // Attempt to cache input, action, and output adapters for routing table calculation. // This could fail if another thread modifies the collections while caching is in // progress (rare), so retry if the caching fails. // // We don't attempt to lock here because we don't own the collections. while (retry) { try { if ((object)m_inputAdapters != null) { inputAdapterCollection = m_inputAdapters.ToArray <IInputAdapter>(); } if ((object)m_actionAdapters != null) { actionAdapterCollection = m_actionAdapters.ToArray <IActionAdapter>(); } if ((object)m_outputAdapters != null) { outputAdapterCollection = m_outputAdapters.ToArray <IOutputAdapter>(); } retry = false; } catch (InvalidOperationException) { // Attempt to catch "Collection was modified; enumeration operation may not execute." } catch (NullReferenceException) { // Catch rare exceptions where IaonSession is disposed during a context switch inputAdapterCollection = null; actionAdapterCollection = null; outputAdapterCollection = null; retry = false; } } try { HashSet <IAdapter> consumerAdapters; HashSet <IAdapter> producerAdapters; // Get a full list of all producer (input/action) adapters producerAdapters = new HashSet <IAdapter>((inputAdapterCollection ?? Enumerable.Empty <IAdapter>()) .Concat(actionAdapterCollection ?? Enumerable.Empty <IAdapter>())); // Get a full list of all consumer (action/output) adapters consumerAdapters = new HashSet <IAdapter>((actionAdapterCollection ?? Enumerable.Empty <IAdapter>()) .Concat(outputAdapterCollection ?? Enumerable.Empty <IAdapter>())); var producerChanges = new RoutingTablesAdaptersList(m_prevCalculatedProducers, producerAdapters); var consumerChanges = new RoutingTablesAdaptersList(m_prevCalculatedConsumers, consumerAdapters); m_routeMappingTables.PatchRoutingTable(producerChanges, consumerChanges); m_prevCalculatedProducers = producerAdapters; m_prevCalculatedConsumers = consumerAdapters; // Start or stop any connect on demand adapters HandleConnectOnDemandAdapters(new HashSet <MeasurementKey>(m_inputMeasurementKeysRestriction ?? Enumerable.Empty <MeasurementKey>()), inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); elapsedTime = Ticks.ToSeconds(DateTime.UtcNow.Ticks - startTime); int routeCount = m_routeMappingTables.RouteCount; int destinationCount = consumerAdapters.Count; OnStatusMessage("Calculated {0} route{1} for {2} destination{3} in {4}.", routeCount, (routeCount == 1) ? "" : "s", destinationCount, (destinationCount == 1) ? "" : "s", elapsedTime.ToString(2)); } catch (ObjectDisposedException) { // Ignore this error. Seems to happen during normal // operation and does not affect the result. } catch (Exception ex) { OnProcessException(new InvalidOperationException("Routing tables calculation error: " + ex.Message, ex)); } }
private void CalculateRoutingTables() { long startTime = DateTime.UtcNow.Ticks; Time elapsedTime; IInputAdapter[] inputAdapterCollection = null; IActionAdapter[] actionAdapterCollection = null; IOutputAdapter[] outputAdapterCollection = null; bool retry = true; OnStatusMessage("Starting measurement route calculation..."); // Attempt to cache input, action, and output adapters for routing table calculation. // This could fail if another thread modifies the collections while caching is in // progress (rare), so retry if the caching fails. // // We don't attempt to lock here because we don't own the collections. while (retry) { try { if ((object)m_inputAdapters != null) inputAdapterCollection = m_inputAdapters.ToArray<IInputAdapter>(); if ((object)m_actionAdapters != null) actionAdapterCollection = m_actionAdapters.ToArray<IActionAdapter>(); if ((object)m_outputAdapters != null) outputAdapterCollection = m_outputAdapters.ToArray<IOutputAdapter>(); retry = false; } catch (InvalidOperationException) { // Attempt to catch "Collection was modified; enumeration operation may not execute." } catch (NullReferenceException) { // Catch rare exceptions where IaonSession is disposed during a context switch inputAdapterCollection = null; actionAdapterCollection = null; outputAdapterCollection = null; retry = false; } } try { HashSet<IAdapter> consumerAdapters; HashSet<IAdapter> producerAdapters; // Get a full list of all producer (input/action) adapters producerAdapters = new HashSet<IAdapter>((inputAdapterCollection ?? Enumerable.Empty<IAdapter>()) .Concat(actionAdapterCollection ?? Enumerable.Empty<IAdapter>())); // Get a full list of all consumer (action/output) adapters consumerAdapters = new HashSet<IAdapter>((actionAdapterCollection ?? Enumerable.Empty<IAdapter>()) .Concat(outputAdapterCollection ?? Enumerable.Empty<IAdapter>())); var producerChanges = new RoutingTablesAdaptersList(m_prevCalculatedProducers, producerAdapters); var consumerChanges = new RoutingTablesAdaptersList(m_prevCalculatedConsumers, consumerAdapters); m_routeMappingTables.PatchRoutingTable(producerChanges, consumerChanges); m_prevCalculatedProducers = producerAdapters; m_prevCalculatedConsumers = consumerAdapters; // Start or stop any connect on demand adapters HandleConnectOnDemandAdapters(new HashSet<MeasurementKey>(m_inputMeasurementKeysRestriction ?? Enumerable.Empty<MeasurementKey>()), inputAdapterCollection, actionAdapterCollection, outputAdapterCollection); elapsedTime = Ticks.ToSeconds(DateTime.UtcNow.Ticks - startTime); int routeCount = m_routeMappingTables.RouteCount; int destinationCount = consumerAdapters.Count; OnStatusMessage("Calculated {0} route{1} for {2} destination{3} in {4}.", routeCount, (routeCount == 1) ? "" : "s", destinationCount, (destinationCount == 1) ? "" : "s", elapsedTime.ToString(2)); } catch (ObjectDisposedException) { // Ignore this error. Seems to happen during normal // operation and does not affect the result. } catch (Exception ex) { OnProcessException(new InvalidOperationException("Routing tables calculation error: " + ex.Message, ex)); } }
/// <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); }