/// <summary> /// Find and block any module whose prerequisites for operation are not present. This minimises the damage caused by /// inconsistent module configuration. Sets up the ModuleSequence property with the operating modules. /// </summary> public void ValidateModules() { foreach (Module module in Modules.Values) { if (module.DependentOn.Any(mn => !Modules.Keys.Any(k => k.StartsWith(mn) && k != module.Name))) { module.Blocked = true; log.ErrorFormat("Module {0} blocked, missing module it depends on", module.Name); module.Error = "Missing module depended on: " + module.Name; } else if (module.IncompatibleWith.Any(mn => Modules.Keys.Any(k => k.StartsWith(mn) && k != module.Name))) { module.Blocked = true; log.ErrorFormat("Module {0} blocked, incompatible module exists", module.Name); module.Error = "Incompatible module exists: " + module.Name; } } var moduleDict = Modules.Values.Where(m => !m.Blocked).ToDictionary(m => m.Name, m => m); var sortedModules = new ConstraintOrderedCollection <Module>(m => m.Name); moduleDict.Values .Do(m => sortedModules.Add(m, new OrderConstraint(m.Name, m.MustFollow, m.MustPrecede))); this.Modules = moduleDict; this.ModuleSequence = sortedModules; }
/// <summary> /// Copy a ConstraintOrderedCollection with all its constraints /// </summary> /// <returns>The copied ConstraintOrderedCollection</returns> public ConstraintOrderedCollection <T> Copy() { var coc = new ConstraintOrderedCollection <T>(this.nameSelector); coc.innerList.AddRange(this.innerList); coc.orderConstraint.AddAnd(this.orderConstraint); return(coc); }
/// <summary> /// Register a function to process event data on raising of an event elsewhere ensuring specified processes on which it /// is dependent are performed first /// </summary> /// <param name="eventName">The name of the event being raised</param> /// <param name="processor">A delegate which takes the current event data and the sender and returns the processed event data</param> /// <param name="moduleId">The name of the module. This can be moduletype.module</param> /// <param name="constraint">An order constraint specifying restrictions on the relative position of this processor in any chain of processors</param> public void RegisterEventProcessor( string eventName, Func <EventHubData, object> processor, string moduleId, OrderConstraint constraint) { var newProcessor = new ProcessorInfo { EventName = eventName, ModuleId = moduleId, Processor = processor }; // register processor on all processor queues where event is or covers a subset of this event var subEvents = Processors.Keys.Where(k => k.StartsWith(eventName)).ToList(); bool matched = false; foreach (string subEvent in subEvents) { if (Processors[subEvent].Any(p => p.ModuleId == newProcessor.ModuleId)) { throw new Exception("Trying to add more than 1 processor for module " + newProcessor.ModuleId + " to event queue " + subEvent); } Processors[subEvent].Add(newProcessor, constraint); matched = (subEvent == eventName); } // if not regstered anywhere, create a new processor queue containing the processes from the least super event of this one if (!matched) { var leastSuperEvent = LeastSuperEvent(eventName); var pList = new ConstraintOrderedCollection <ProcessorInfo>(pi => pi.ModuleId); if (leastSuperEvent != null) { pList = Processors[leastSuperEvent].Copy(); } pList.Add(newProcessor, constraint); Processors.Add(eventName, pList); } }