/// <summary> /// Static failure resolution constructor. /// </summary> public YodiiEngineResult(IConfigurationSolver solver, List <PluginData> blockingPlugins, List <ServiceData> blockingServices, YodiiEngine engine) { Debug.Assert(blockingPlugins != null || blockingServices != null, "At least one must not be null."); Debug.Assert(solver != null); Debug.Assert(engine != null); var allP = solver.AllPlugins.Select(p => new SolvedPluginSnapshot(p)).ToDictionary(p => p.PluginInfo); var allS = solver.AllServices.Select(s => new SolvedServiceSnapshot(s)).ToDictionary(s => s.ServiceInfo.ServiceFullName); _staticOnlyResultConfiguration = new StaticSolvedConfiguration(allP.Values.ToReadOnlyList(), allS.Values.ToReadOnlyList()); var blkP = blockingPlugins == null ? CKReadOnlyListEmpty <IStaticSolvedPlugin> .Empty : blockingPlugins.Select(p => allP[p.PluginInfo]).ToReadOnlyList(); _pluginCulprits = blkP.Select(ps => ps.PluginInfo).ToReadOnlyList(); var blkS = blockingServices == null ? CKReadOnlyListEmpty <IStaticSolvedService> .Empty : blockingServices.Select(s => allS[s.ServiceInfo.ServiceFullName]).ToReadOnlyList(); _serviceCulprits = blkS.Select(ss => ss.ServiceInfo).ToReadOnlyList(); _engine = engine; _staticFailureResult = new StaticFailureResult(_staticOnlyResultConfiguration, blkP, blkS); }
internal ServiceData(IConfigurationSolver solver, IServiceInfo s, ConfigurationStatus serviceStatus, StartDependencyImpact impact = StartDependencyImpact.Unknown) : this(s, serviceStatus, impact) { Family = new ServiceFamily(solver, this); _inheritedServicesWithThis = new ServiceData[] { this }; Initialize(); }
/// <summary> /// Static only success resolution constructor. /// </summary> public YodiiEngineResult( IConfigurationSolver solver, YodiiEngine engine ) { Debug.Assert( solver != null ); Debug.Assert( engine != null ); var allP = solver.AllPlugins.Select( p => new SolvedPluginSnapshot( p ) ).ToDictionary( p => p.PluginInfo ); var allS = solver.AllServices.Select( s => new SolvedServiceSnapshot( s ) ).ToDictionary( s => s.ServiceInfo.ServiceFullName ); _staticOnlyResultConfiguration = new StaticSolvedConfiguration( allP.Values.ToReadOnlyList(), allS.Values.ToReadOnlyList() ); _pluginCulprits = CKReadOnlyListEmpty<IPluginInfo>.Empty; _serviceCulprits = CKReadOnlyListEmpty<IServiceInfo>.Empty; _engine = engine; }
/// <summary> /// Static only success resolution constructor. /// </summary> public YodiiEngineResult(IConfigurationSolver solver, YodiiEngine engine) { Debug.Assert(solver != null); Debug.Assert(engine != null); var allP = solver.AllPlugins.Select(p => new SolvedPluginSnapshot(p)).ToDictionary(p => p.PluginInfo); var allS = solver.AllServices.Select(s => new SolvedServiceSnapshot(s)).ToDictionary(s => s.ServiceInfo.ServiceFullName); _staticOnlyResultConfiguration = new StaticSolvedConfiguration(allP.Values.ToReadOnlyList(), allS.Values.ToReadOnlyList()); _pluginCulprits = CKReadOnlyListEmpty <IPluginInfo> .Empty; _serviceCulprits = CKReadOnlyListEmpty <IServiceInfo> .Empty; _engine = engine; }
/// <summary> /// Dynamic failure constructor. /// </summary> internal YodiiEngineResult( IConfigurationSolver solver, IEnumerable<Tuple<IPluginInfo, Exception>> errorInfo, YodiiEngine engine ) { Debug.Assert( solver != null ); Debug.Assert( errorInfo != null && errorInfo.Any() ); Debug.Assert( engine != null ); var allP = solver.AllPlugins.Select( p => new SolvedPluginSnapshot( p ) ).ToDictionary( ps => ps.PluginInfo ); var allS = solver.AllServices.Select( s => new SolvedServiceSnapshot( s ) ).ToReadOnlyList(); var errors = errorInfo.Select( e => new PluginRuntimeError( allP[e.Item1], e.Item2 ) ).ToReadOnlyList(); _pluginCulprits = errors.Select( e => e.Plugin.PluginInfo ).ToReadOnlyList(); _serviceCulprits = _pluginCulprits.Select( p => p.Service ).Where( s => s != null ).ToReadOnlyList(); _engine = engine; _hostFailureResult = new DynamicFailureResult( new DynamicSolvedConfiguration( allP.Values.ToReadOnlyList(), allS ), errors ); }
/// <summary> /// Dynamic failure constructor. /// </summary> internal YodiiEngineResult(IConfigurationSolver solver, IEnumerable <Tuple <IPluginInfo, Exception> > errorInfo, YodiiEngine engine) { Debug.Assert(solver != null); Debug.Assert(errorInfo != null && errorInfo.Any()); Debug.Assert(engine != null); var allP = solver.AllPlugins.Select(p => new SolvedPluginSnapshot(p)).ToDictionary(ps => ps.PluginInfo); var allS = solver.AllServices.Select(s => new SolvedServiceSnapshot(s)).ToReadOnlyList(); var errors = errorInfo.Select(e => new PluginRuntimeError(allP[e.Item1], e.Item2)).ToReadOnlyList(); _pluginCulprits = errors.Select(e => e.Plugin.PluginInfo).ToReadOnlyList(); _serviceCulprits = _pluginCulprits.Select(p => p.Service).Where(s => s != null).ToReadOnlyList(); _engine = engine; _hostFailureResult = new DynamicFailureResult(new DynamicSolvedConfiguration(allP.Values.ToReadOnlyList(), allS), errors); }
/// <summary> /// Static failure resolution constructor. /// </summary> public YodiiEngineResult( IConfigurationSolver solver, List<PluginData> blockingPlugins, List<ServiceData> blockingServices, YodiiEngine engine ) { Debug.Assert( blockingPlugins != null || blockingServices != null, "At least one must not be null." ); Debug.Assert( solver != null ); Debug.Assert( engine != null ); var allP = solver.AllPlugins.Select( p => new SolvedPluginSnapshot( p ) ).ToDictionary( p => p.PluginInfo ); var allS = solver.AllServices.Select( s => new SolvedServiceSnapshot( s ) ).ToDictionary( s => s.ServiceInfo.ServiceFullName ); _staticOnlyResultConfiguration = new StaticSolvedConfiguration( allP.Values.ToReadOnlyList(), allS.Values.ToReadOnlyList() ); var blkP = blockingPlugins == null ? CKReadOnlyListEmpty<IStaticSolvedPlugin>.Empty : blockingPlugins.Select( p => allP[p.PluginInfo] ).ToReadOnlyList(); _pluginCulprits = blkP.Select( ps => ps.PluginInfo ).ToReadOnlyList(); var blkS = blockingServices == null ? CKReadOnlyListEmpty<IStaticSolvedService>.Empty : blockingServices.Select( s => allS[s.ServiceInfo.ServiceFullName] ).ToReadOnlyList(); _serviceCulprits = blkS.Select( ss => ss.ServiceInfo ).ToReadOnlyList(); _engine = engine; _staticFailureResult = new StaticFailureResult( _staticOnlyResultConfiguration, blkP, blkS ); }
public ServiceFamily(IConfigurationSolver solver, ServiceData root) { Solver = solver; Root = root; _availableServices = new HashSet <ServiceData>(); }
internal ServiceData( IConfigurationSolver solver, IServiceInfo s, ConfigurationStatus serviceStatus, StartDependencyImpact impact = StartDependencyImpact.Unknown ) : this(s, serviceStatus, impact) { Family = new ServiceFamily( solver, this ); _inheritedServicesWithThis = new ServiceData[] { this }; Initialize(); }
internal void UpdateFrom( IConfigurationSolver solver ) { // 1 - Removes existing items from live info that do not exist anymore in the new running context. // This raises Collection "item removed" events. // _services.RemoveWhereAndReturnsRemoved( s => solver.FindService( s.ServiceInfo.ServiceFullName ) == null ).Count(); _plugins.RemoveWhereAndReturnsRemoved( p => solver.FindPlugin( p.PluginInfo.PluginFullName ) == null ).Count(); DelayedPropertyNotification notifier = new DelayedPropertyNotification(); // 2 - Builds two lists of new Services and new Plugins and for already existing ones, // updates them with the new information. // This update does not trigger any ProprtyChanged events and consider only // direct properties of the object. // Changes to linked items (such as a Generalization reference for instance will be // done later thanks to their Bind method. // List<LiveServiceInfo> servicesToAdd = new List<LiveServiceInfo>(); foreach( var s in solver.AllServices ) { LiveServiceInfo ls = _services.GetByKey( s.ServiceInfo.ServiceFullName ); if( ls == null ) servicesToAdd.Add( new LiveServiceInfo( s, _engine ) ); else ls.UpdateFrom( s, notifier ); } List<LivePluginInfo> pluginsToAdd = new List<LivePluginInfo>(); foreach( var p in solver.AllPlugins ) { LivePluginInfo lp = _plugins.GetByKey( p.PluginInfo.PluginFullName ); if( lp == null ) pluginsToAdd.Add( new LivePluginInfo( p, _engine ) ); else lp.UpdateFrom( p, notifier ); } // 3 - Intrinsic properties have been updated. We now consider the properties that reference other items. // Func<string,LiveServiceInfo> serviceFinder = name => _services.GetByKey( name ) ?? servicesToAdd.First( ls => ls.ServiceInfo.ServiceFullName == name ); Func<string,LivePluginInfo> pluginFinder = id => _plugins.GetByKey( id ) ?? pluginsToAdd.First( lp => lp.PluginInfo.PluginFullName == id ); using( notifier.SilentMode() ) { foreach( var ls in servicesToAdd ) ls.Bind( solver.FindExistingService( ls.ServiceInfo.ServiceFullName ), serviceFinder, pluginFinder, notifier ); } foreach( var ls in _services ) ls.Bind( solver.FindExistingService( ls.ServiceInfo.ServiceFullName ), serviceFinder, pluginFinder, notifier ); using( notifier.SilentMode() ) { foreach( var lp in pluginsToAdd ) lp.Bind( solver.FindExistingPlugin( lp.PluginInfo.PluginFullName ), serviceFinder, notifier ); } foreach( var lp in _plugins ) lp.Bind( solver.FindExistingPlugin( lp.PluginInfo.PluginFullName ), serviceFinder, notifier ); // 4 - It is time to add the new comers: this raises Collection changed "item added" events. foreach( var ls in servicesToAdd ) _services.Add( ls ); foreach( var lp in pluginsToAdd ) _plugins.Add( lp ); // 5 - Raises all PropertyChanged events for all objects. notifier.RaiseEvents(); }
internal PluginData(IConfigurationSolver solver, IPluginInfo p, ServiceData service, ConfigurationStatus pluginStatus, StartDependencyImpact impact = StartDependencyImpact.Unknown) { _solver = solver; PluginInfo = p; Service = service; ConfigOriginalStatus = pluginStatus; switch (pluginStatus) { case ConfigurationStatus.Disabled: _configSolvedStatus = SolvedConfigurationStatus.Disabled; break; case ConfigurationStatus.Running: _configSolvedStatus = SolvedConfigurationStatus.Running; break; default: _configSolvedStatus = SolvedConfigurationStatus.Runnable; break; } _configSolvedStatusReason = PluginRunningRequirementReason.Config; RawConfigSolvedImpact = ConfigOriginalImpact = impact; if (RawConfigSolvedImpact == StartDependencyImpact.Unknown && Service != null) { RawConfigSolvedImpact = Service.ConfigSolvedImpact; } _configSolvedImpact = RawConfigSolvedImpact; if (_configSolvedImpact == StartDependencyImpact.Unknown || (_configSolvedImpact & StartDependencyImpact.IsTryOnly) != 0) { _configSolvedImpact = StartDependencyImpact.Minimal; } if (ConfigOriginalStatus == ConfigurationStatus.Disabled) { _configDisabledReason = PluginDisabledReason.Config; } else if (p.HasError) { _configDisabledReason = PluginDisabledReason.PluginInfoHasError; } else if (Service != null) { if (Service.Disabled) { _configDisabledReason = PluginDisabledReason.ServiceIsDisabled; } else if (Service.Family.RunningPlugin != null) { _configDisabledReason = PluginDisabledReason.AnotherRunningPluginExistsInFamilyByConfig; } } // Immediately check for Runnable references to Disabled Services: this disables us. if (!Disabled) { foreach (var sRef in PluginInfo.ServiceReferences) { if (sRef.Requirement >= DependencyRequirement.Runnable) { // If the required service is already disabled, we immediately disable this plugin. if (sRef.Reference.HasError && !Disabled) { _configDisabledReason = PluginDisabledReason.RunnableReferenceServiceIsOnError; break; } ServiceData sr = _solver.FindExistingService(sRef.Reference.ServiceFullName); if (sr.Disabled && !Disabled) { _configDisabledReason = PluginDisabledReason.RunnableReferenceIsDisabled; break; } } } } if (Service != null) { Service.AddPlugin(this); } if (!Disabled) { // If the plugin is not yet disabled, we register it: // whenever the referenced service is disabled (or stopped during dynamic resolution), this // will disable (or stop) the plugin according to its ConfigSolvedImpact. foreach (var sRef in PluginInfo.ServiceReferences) { _solver.FindExistingService(sRef.Reference.ServiceFullName).RegisterPluginReference(this, sRef.Requirement); } if (Service != null && ConfigOriginalStatus == ConfigurationStatus.Running) { Service.Family.SetRunningPlugin(this); } } }
public ServiceFamily( IConfigurationSolver solver, ServiceData root ) { Solver = solver; Root = root; _availableServices = new HashSet<ServiceData>(); }
internal void UpdateFrom(IConfigurationSolver solver) { // 1 - Removes existing items from live info that do not exist anymore in the new running context. // This raises Collection "item removed" events. // _services.RemoveWhereAndReturnsRemoved(s => solver.FindService(s.ServiceInfo.ServiceFullName) == null).Count(); _plugins.RemoveWhereAndReturnsRemoved(p => solver.FindPlugin(p.PluginInfo.PluginFullName) == null).Count(); DelayedPropertyNotification notifier = new DelayedPropertyNotification(); // 2 - Builds two lists of new Services and new Plugins and for already existing ones, // updates them with the new information. // This update does not trigger any ProprtyChanged events and consider only // direct properties of the object. // Changes to linked items (such as a Generalization reference for instance will be // done later thanks to their Bind method. // List <LiveServiceInfo> servicesToAdd = new List <LiveServiceInfo>(); foreach (var s in solver.AllServices) { LiveServiceInfo ls = _services.GetByKey(s.ServiceInfo.ServiceFullName); if (ls == null) { servicesToAdd.Add(new LiveServiceInfo(s, _engine)); } else { ls.UpdateFrom(s, notifier); } } List <LivePluginInfo> pluginsToAdd = new List <LivePluginInfo>(); foreach (var p in solver.AllPlugins) { LivePluginInfo lp = _plugins.GetByKey(p.PluginInfo.PluginFullName); if (lp == null) { pluginsToAdd.Add(new LivePluginInfo(p, _engine)); } else { lp.UpdateFrom(p, notifier); } } // 3 - Intrinsic properties have been updated. We now consider the properties that reference other items. // Func <string, LiveServiceInfo> serviceFinder = name => _services.GetByKey(name) ?? servicesToAdd.First(ls => ls.ServiceInfo.ServiceFullName == name); Func <string, LivePluginInfo> pluginFinder = id => _plugins.GetByKey(id) ?? pluginsToAdd.First(lp => lp.PluginInfo.PluginFullName == id); using (notifier.SilentMode()) { foreach (var ls in servicesToAdd) { ls.Bind(solver.FindExistingService(ls.ServiceInfo.ServiceFullName), serviceFinder, pluginFinder, notifier); } } foreach (var ls in _services) { ls.Bind(solver.FindExistingService(ls.ServiceInfo.ServiceFullName), serviceFinder, pluginFinder, notifier); } using (notifier.SilentMode()) { foreach (var lp in pluginsToAdd) { lp.Bind(solver.FindExistingPlugin(lp.PluginInfo.PluginFullName), serviceFinder, notifier); } } foreach (var lp in _plugins) { lp.Bind(solver.FindExistingPlugin(lp.PluginInfo.PluginFullName), serviceFinder, notifier); } // 4 - It is time to add the new comers: this raises Collection changed "item added" events. foreach (var ls in servicesToAdd) { _services.Add(ls); } foreach (var lp in pluginsToAdd) { _plugins.Add(lp); } // 5 - Raises all PropertyChanged events for all objects. notifier.RaiseEvents(); }
internal PluginData( IConfigurationSolver solver, IPluginInfo p, ServiceData service, ConfigurationStatus pluginStatus, StartDependencyImpact impact = StartDependencyImpact.Unknown ) { _solver = solver; PluginInfo = p; Service = service; ConfigOriginalStatus = pluginStatus; switch( pluginStatus ) { case ConfigurationStatus.Disabled: _configSolvedStatus = SolvedConfigurationStatus.Disabled; break; case ConfigurationStatus.Running: _configSolvedStatus = SolvedConfigurationStatus.Running; break; default: _configSolvedStatus = SolvedConfigurationStatus.Runnable; break; } _configSolvedStatusReason = PluginRunningRequirementReason.Config; RawConfigSolvedImpact = ConfigOriginalImpact = impact; if( RawConfigSolvedImpact == StartDependencyImpact.Unknown && Service != null ) { RawConfigSolvedImpact = Service.ConfigSolvedImpact; } _configSolvedImpact = RawConfigSolvedImpact; if( _configSolvedImpact == StartDependencyImpact.Unknown || (_configSolvedImpact & StartDependencyImpact.IsTryOnly) != 0 ) { _configSolvedImpact = StartDependencyImpact.Minimal; } if( ConfigOriginalStatus == ConfigurationStatus.Disabled ) { _configDisabledReason = PluginDisabledReason.Config; } else if( p.HasError ) { _configDisabledReason = PluginDisabledReason.PluginInfoHasError; } else if( Service != null ) { if( Service.Disabled ) { _configDisabledReason = PluginDisabledReason.ServiceIsDisabled; } else if( Service.Family.RunningPlugin != null ) { _configDisabledReason = PluginDisabledReason.AnotherRunningPluginExistsInFamilyByConfig; } } // Immediately check for Runnable references to Disabled Services: this disables us. if( !Disabled ) { foreach( var sRef in PluginInfo.ServiceReferences ) { if( sRef.Requirement >= DependencyRequirement.Runnable ) { // If the required service is already disabled, we immediately disable this plugin. if( sRef.Reference.HasError && !Disabled ) { _configDisabledReason = PluginDisabledReason.RunnableReferenceServiceIsOnError; break; } ServiceData sr = _solver.FindExistingService( sRef.Reference.ServiceFullName ); if( sr.Disabled && !Disabled ) { _configDisabledReason = PluginDisabledReason.RunnableReferenceIsDisabled; break; } } } } if( Service != null ) Service.AddPlugin( this ); if( !Disabled ) { // If the plugin is not yet disabled, we register it: // whenever the referenced service is disabled (or stopped during dynamic resolution), this // will disable (or stop) the plugin according to its ConfigSolvedImpact. foreach( var sRef in PluginInfo.ServiceReferences ) { _solver.FindExistingService( sRef.Reference.ServiceFullName ).RegisterPluginReference( this, sRef.Requirement ); } if( Service != null && ConfigOriginalStatus == ConfigurationStatus.Running ) { Service.Family.SetRunningPlugin( this ); } } }