/// <summary> /// Initializes a new StaticPropagation. /// </summary> protected BasePropagation( ServiceData s ) { Service = s; _inclServices = new IEnumerable<ServiceData>[12]; _exclServices = new IEnumerable<ServiceData>[6]; _nbTotalAvailablePlugins = -1; _nbAvailablePlugins = -1; _nbAvailableServices = -1; }
public void DynamicSetRunningService( ServiceData s, ServiceRunningStatusReason reason ) { Debug.Assert( s != null && s.Family == this && !s.Disabled ); Debug.Assert( _dynRunningPlugin == null || s.IsGeneralizationOf( _dynRunningPlugin.Service ), "If there is running plugin, it can only be one of us." ); Debug.Assert( s._dynamicStatus == null || s._dynamicStatus.Value >= RunningStatus.Running ); if( s._dynamicStatus == null ) { s._dynamicStatus = RunningStatus.Running; s._dynamicReason = reason; } if( s == _dynRunningService ) return; Debug.Assert( _dynRunningService == null || _dynRunningService.IsStrictGeneralizationOf( s ), "If there is already a current running service, it can only be a more specialized one." ); var g = s.Generalization; while( g != null ) { if( g._dynamicStatus == null ) { g._dynamicStatus = RunningStatus.Running; g._dynamicReason = ServiceRunningStatusReason.StartedBySpecialization; } g = g.Generalization; } var prevRunningService = _dynRunningService; _dynRunningService = s; // We must now stop sibling services (and plugins) from this up to the currently running one and // when the current one is null, up to the root. g = s.Generalization; var specRunning = s; while( g != null ) { var spec = g.FirstSpecialization; while( spec != null ) { if( spec != specRunning && !spec.Disabled ) { Debug.Assert( spec.DynamicStatus == null || spec.DynamicStatus.Value <= RunningStatus.Stopped ); if( spec.DynamicStatus == null ) spec.DynamicStopBy( ServiceRunningStatusReason.StoppedByGeneralization ); } spec = spec.NextSpecialization; } PluginData p = g.FirstPlugin; while( p != null ) { Debug.Assert( p.DynamicStatus == null || p.DynamicStatus.Value <= RunningStatus.Stopped ); if( p.DynamicStatus == null ) p.DynamicStopBy( PluginRunningStatusReason.StoppedByStoppedService ); p = p.NextPluginForService; } specRunning = g; g = g.Generalization; if( prevRunningService != null && g == prevRunningService.Generalization ) break; } }
/// <summary> /// Initializes a new DynamicPropagation based on the StaticPropagation. /// </summary> protected BasePropagation( BasePropagation staticPropagation ) : this(staticPropagation.Service) { Service = staticPropagation.Service; _nbTotalAvailablePlugins = staticPropagation._nbTotalAvailablePlugins; _nbAvailablePlugins = staticPropagation._nbAvailablePlugins; _nbAvailableServices = staticPropagation._nbAvailableServices; _theOnlyPlugin = staticPropagation._theOnlyPlugin; _theOnlyService = staticPropagation._theOnlyService; if( _theOnlyPlugin != null && _theOnlyService != null ) { Copy( staticPropagation._inclServices, _inclServices ); Copy( staticPropagation._exclServices, _exclServices ); } }
internal void Bind( ServiceData s, Func<string, LiveServiceInfo> serviceFinder, Func<string, LivePluginInfo> pluginFinder, DelayedPropertyNotification notifier ) { var newGeneralization = s.Generalization != null ? serviceFinder( s.Generalization.ServiceInfo.ServiceFullName ) : null; notifier.Update( this, ref _generalization, newGeneralization, () => Generalization ); var familyRunning = s.Family.DynRunningPlugin; Debug.Assert( IsRunning == (familyRunning != null && s.IsGeneralizationOf( familyRunning.Service )) ); ILivePluginInfo newRunningPlugin = null; if( IsRunning ) { newRunningPlugin = pluginFinder( familyRunning.PluginInfo.PluginFullName ); } if( _runningPlugin != null ) { notifier.Update( this, ref _lastRunningPlugin, _runningPlugin, () => LastRunningPlugin ); } notifier.Update( this, ref _runningPlugin, newRunningPlugin, () => RunningPlugin ); }
internal void Bind(ServiceData s, Func <string, LiveServiceInfo> serviceFinder, Func <string, LivePluginInfo> pluginFinder, DelayedPropertyNotification notifier) { var newGeneralization = s.Generalization != null?serviceFinder(s.Generalization.ServiceInfo.ServiceFullName) : null; notifier.Update(this, ref _generalization, newGeneralization, () => Generalization); var familyRunning = s.Family.DynRunningPlugin; Debug.Assert(IsRunning == (familyRunning != null && s.IsGeneralizationOf(familyRunning.Service))); ILivePluginInfo newRunningPlugin = null; if (IsRunning) { newRunningPlugin = pluginFinder(familyRunning.PluginInfo.PluginFullName); } if (_runningPlugin != null) { notifier.Update(this, ref _lastRunningPlugin, _runningPlugin, () => LastRunningPlugin); } notifier.Update(this, ref _runningPlugin, newRunningPlugin, () => RunningPlugin); }
/// <summary> /// Called before DynamicResetState on plugins. /// </summary> public void DynamicResetState() { _dynPropagation = null; _dynamicTotalAvailablePluginsCount = TotalAvailablePluginCount; _dynamicAvailablePluginsCount = AvailablePluginCount; _dynamicAvailableServicesCount = AvailableServiceCount; switch (FinalConfigSolvedStatus) { case SolvedConfigurationStatus.Disabled: { _dynamicReason = ServiceRunningStatusReason.StoppedByConfig; _dynamicStatus = RunningStatus.Disabled; break; } case SolvedConfigurationStatus.Running: { _dynamicReason = ServiceRunningStatusReason.StartedByConfig; _dynamicStatus = RunningStatus.RunningLocked; break; } default: { _dynamicReason = ServiceRunningStatusReason.None; _dynamicStatus = null; break; } } ServiceData s = FirstSpecialization; while (s != null) { s.DynamicResetState(); s = s.NextSpecialization; } }
public void DynamicSetRunningPlugin(PluginData running) { Debug.Assert(running.Service != null && running.Service.Family == this); Debug.Assert(running != null && running.DynamicStatus.HasValue && running.DynamicStatus.Value >= RunningStatus.Running); Debug.Assert(_dynRunningPlugin == null); _dynRunningPlugin = running; DynamicSetRunningService(running.Service, ServiceRunningStatusReason.StartedBySpecialization); // Stops all plugins except the one that started. PluginData p = running.Service.FirstPlugin; while (p != null) { if (p != running) { Debug.Assert(p.DynamicStatus == null || p.DynamicStatus.Value <= RunningStatus.Stopped); if (p.DynamicStatus == null) { p.DynamicStopBy(PluginRunningStatusReason.StoppedByRunningSibling); } } p = p.NextPluginForService; } // Stops all specializations. ServiceData s = running.Service.FirstSpecialization; while (s != null) { Debug.Assert(s.DynamicStatus == null || s.DynamicStatus.Value <= RunningStatus.Stopped); if (s.DynamicStatus == null) { s.DynamicStopBy(ServiceRunningStatusReason.StoppedByGeneralization); } s = s.NextSpecialization; } }
protected override bool IsValidSpecialization(ServiceData s) { return(s.DynamicStatus == null || s.DynamicStatus.Value >= RunningStatus.Running); }
internal void UpdateFrom(ServiceData s, DelayedPropertyNotification notifier) { UpdateItem(s, notifier); notifier.Update(this, ref _serviceInfo, s.ServiceInfo, () => ServiceInfo); }
protected override bool IsValidSpecialization(ServiceData s) { return(!s.Disabled); }
internal void DynamicResetState() { _dynRunningService = null; _dynRunningPlugin = null; Root.DynamicResetState(); }
public SolvedServiceSnapshot(ServiceData s) : base(s) { _serviceInfo = s.ServiceInfo; }
protected override BasePropagation GetPropagationInfo( ServiceData s ) { return s.GetUsefulPropagationInfo(); }
public StaticPropagation( ServiceData s ) : base(s) { }
protected abstract bool IsValidSpecialization(ServiceData s);
public void DynamicSetRunningService(ServiceData s, ServiceRunningStatusReason reason) { Debug.Assert(s != null && s.Family == this && !s.Disabled); Debug.Assert(_dynRunningPlugin == null || s.IsGeneralizationOf(_dynRunningPlugin.Service), "If there is running plugin, it can only be one of us."); Debug.Assert(s._dynamicStatus == null || s._dynamicStatus.Value >= RunningStatus.Running); if (s._dynamicStatus == null) { s._dynamicStatus = RunningStatus.Running; s._dynamicReason = reason; } if (s == _dynRunningService) { return; } Debug.Assert(_dynRunningService == null || _dynRunningService.IsStrictGeneralizationOf(s), "If there is already a current running service, it can only be a more specialized one."); var g = s.Generalization; while (g != null) { if (g._dynamicStatus == null) { g._dynamicStatus = RunningStatus.Running; g._dynamicReason = ServiceRunningStatusReason.StartedBySpecialization; } g = g.Generalization; } var prevRunningService = _dynRunningService; _dynRunningService = s; // We must now stop sibling services (and plugins) from this up to the currently running one and // when the current one is null, up to the root. g = s.Generalization; var specRunning = s; while (g != null) { var spec = g.FirstSpecialization; while (spec != null) { if (spec != specRunning && !spec.Disabled) { Debug.Assert(spec.DynamicStatus == null || spec.DynamicStatus.Value <= RunningStatus.Stopped); if (spec.DynamicStatus == null) { spec.DynamicStopBy(ServiceRunningStatusReason.StoppedByGeneralization); } } spec = spec.NextSpecialization; } PluginData p = g.FirstPlugin; while (p != null) { Debug.Assert(p.DynamicStatus == null || p.DynamicStatus.Value <= RunningStatus.Stopped); if (p.DynamicStatus == null) { p.DynamicStopBy(PluginRunningStatusReason.StoppedByStoppedService); } p = p.NextPluginForService; } specRunning = g; g = g.Generalization; if (prevRunningService != null && g == prevRunningService.Generalization) { break; } } }
public IEnumerable <ServiceData> GetIncludedServices(StartDependencyImpact impact, bool forRunnableStatus) { if (_runningIncludedServices == null) { var running = Service != null ? new HashSet <ServiceData>(Service.InheritedServicesWithThis) : new HashSet <ServiceData>(); foreach (var sRef in PluginInfo.ServiceReferences) { if (sRef.Requirement == DependencyRequirement.Running) { running.Add(_solver.FindExistingService(sRef.Reference.ServiceFullName)); } } _runningIncludedServices = running.ToReadOnlyList(); bool newRunnableAdded = false; foreach (var sRef in PluginInfo.ServiceReferences) { if (sRef.Requirement == DependencyRequirement.Runnable) { newRunnableAdded |= running.Add(_solver.FindExistingService(sRef.Reference.ServiceFullName)); } } _runnableIncludedServices = newRunnableAdded ? running.ToReadOnlyList() : _runningIncludedServices; } if (impact == StartDependencyImpact.Minimal) { return(forRunnableStatus ? _runnableIncludedServices : _runningIncludedServices); } if (_inclServices == null) { _inclServices = new IReadOnlyList <ServiceData> [8]; } int iImpact = (int)impact; if (impact > StartDependencyImpact.Minimal) { --impact; } if (forRunnableStatus) { iImpact *= 2; } --iImpact; IReadOnlyList <ServiceData> i = _inclServices[iImpact]; if (i == null) { var baseSet = forRunnableStatus ? _runnableIncludedServices : _runningIncludedServices; var incl = new HashSet <ServiceData>(baseSet); bool newAdded = false; foreach (var sRef in PluginInfo.ServiceReferences) { ServiceData sr = _solver.FindExistingService(sRef.Reference.ServiceFullName); switch (sRef.Requirement) { case DependencyRequirement.RunnableRecommended: { if (impact >= StartDependencyImpact.StartRecommended) { newAdded |= incl.Add(sr); } break; } case DependencyRequirement.Runnable: { if (impact == StartDependencyImpact.FullStart) { newAdded |= incl.Add(sr); } break; } case DependencyRequirement.OptionalRecommended: { if (impact >= StartDependencyImpact.StartRecommended) { newAdded |= incl.Add(sr); } break; } case DependencyRequirement.Optional: { if (impact == StartDependencyImpact.FullStart) { newAdded |= incl.Add(sr); } break; } } } i = _inclServices[iImpact] = newAdded ? incl.ToReadOnlyList() : baseSet; } return(i); }
public IEnumerable <ServiceData> GetExcludedServices(StartDependencyImpact impact) { if (_exclServices == null) { _exclServices = new IReadOnlyList <ServiceData> [6]; } IReadOnlyList <ServiceData> e = _exclServices[(int)impact - 1]; if (e == null) { HashSet <ServiceData> excl = new HashSet <ServiceData>(); foreach (var sRef in PluginInfo.ServiceReferences) { ServiceData sr = _solver.FindExistingService(sRef.Reference.ServiceFullName); switch (sRef.Requirement) { case DependencyRequirement.Running: { excl.UnionWith(sr.DirectExcludedServices); break; } case DependencyRequirement.RunnableRecommended: { if (impact >= StartDependencyImpact.StartRecommended) { excl.UnionWith(sr.DirectExcludedServices); } else if (impact == StartDependencyImpact.FullStop) { excl.Add(sr); } break; } case DependencyRequirement.Runnable: { if (impact == StartDependencyImpact.FullStart) { excl.UnionWith(sr.DirectExcludedServices); } else if (impact <= StartDependencyImpact.StopOptionalAndRunnable) { excl.Add(sr); } break; } case DependencyRequirement.OptionalRecommended: { if (impact >= StartDependencyImpact.StartRecommended) { excl.UnionWith(sr.DirectExcludedServices); } else if (impact == StartDependencyImpact.FullStop) { excl.Add(sr); } break; } case DependencyRequirement.Optional: { if (impact == StartDependencyImpact.FullStart) { excl.UnionWith(sr.DirectExcludedServices); } else if (impact <= StartDependencyImpact.StopOptionalAndRunnable) { excl.Add(sr); } break; } } } e = _exclServices[(int)impact - 1] = excl.ToReadOnlyList(); } return(e); }
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); } } }
internal void DynamicStopBy(ServiceRunningStatusReason reason) { Debug.Assert(_dynamicStatus == null); Debug.Assert(reason == ServiceRunningStatusReason.StoppedByGeneralization || reason == ServiceRunningStatusReason.StoppedByCommand || reason == ServiceRunningStatusReason.StoppedByPluginStopped || reason == ServiceRunningStatusReason.StoppedBySiblingRunningService || reason == ServiceRunningStatusReason.StoppedByOptionalReference || reason == ServiceRunningStatusReason.StoppedByOptionalRecommendedReference || reason == ServiceRunningStatusReason.StoppedByRunnableReference || reason == ServiceRunningStatusReason.StoppedByRunnableRecommendedReference || reason == ServiceRunningStatusReason.StoppedByFinalDecision); _dynamicStatus = RunningStatus.Stopped; _dynamicReason = reason; for (int i = 0; i < _inheritedServicesWithThis.Length - 1; ++i) { --_inheritedServicesWithThis[i]._dynamicAvailableServicesCount; } if (_dynamicTotalAvailablePluginsCount > 0) { // Stops the specialized services. ServiceData child = FirstSpecialization; while (child != null) { Debug.Assert(child.DynamicStatus == null || child.DynamicStatus.Value <= RunningStatus.Stopped); if (child.DynamicStatus == null) { child.DynamicStopBy(ServiceRunningStatusReason.StoppedByGeneralization); } child = child.NextSpecialization; } // Stops the plugins. PluginData p = FirstPlugin; while (p != null) { Debug.Assert(p.DynamicStatus == null || p.DynamicStatus.Value <= RunningStatus.Stopped); if (p.DynamicStatus == null) { p.DynamicStopBy(PluginRunningStatusReason.StoppedByStoppedService); } p = p.NextPluginForService; } Debug.Assert(_dynamicTotalAvailablePluginsCount == 0); } foreach (var backRef in _backReferences) { Debug.Assert(backRef.PluginData.DynamicStatus == null || backRef.PluginData.DynamicStatus.Value <= RunningStatus.Stopped || ((backRef.Requirement == DependencyRequirement.Optional || backRef.Requirement == DependencyRequirement.Runnable) && backRef.PluginData.ConfigSolvedImpact != StartDependencyImpact.FullStart) || ((backRef.Requirement == DependencyRequirement.OptionalRecommended || backRef.Requirement == DependencyRequirement.RunnableRecommended) && backRef.PluginData.ConfigSolvedImpact < StartDependencyImpact.StartRecommended)); if (backRef.PluginData.DynamicStatus == null) { PluginRunningStatusReason r = backRef.PluginData.GetStoppedReasonForStoppedReference(backRef.Requirement); if (r != PluginRunningStatusReason.None) { backRef.PluginData.DynamicStopBy(r); } } } }
public ServiceFamily( IConfigurationSolver solver, ServiceData root ) { Solver = solver; Root = root; _availableServices = new HashSet<ServiceData>(); }
internal LiveServiceInfo(ServiceData s, YodiiEngine engine) : base(engine, s, s.ServiceInfo.ServiceFullName) { _serviceInfo = s.ServiceInfo; }
void IConfigurationSolver.DeferPropagation(ServiceData s) { _deferedPropagation.Add(s); }
/// <summary> /// Tests whether this service is a generalization of another one. /// </summary> /// <param name="s">Service that is a potential specialization.</param> /// <returns>True if this generalizes <paramref name="s"/>.</returns> internal bool IsStrictGeneralizationOf( ServiceData s ) { var g = s.Generalization; if( g == null || s.Family != Family ) return false; do { if( g == this ) return true; g = g.Generalization; } while( g != null ); return false; }
protected abstract BasePropagation GetPropagationInfo( ServiceData s );
protected override bool IsValidSpecialization( ServiceData s ) { return !s.Disabled; }
protected void Refresh( int nbTotalAvalaiblePlugins, int nbAvailablePlugins, int nbAvailableServices ) { if( _nbTotalAvailablePlugins == nbTotalAvalaiblePlugins && _nbAvailablePlugins == nbAvailablePlugins && _nbAvailableServices == nbAvailableServices ) return; _nbTotalAvailablePlugins = nbTotalAvalaiblePlugins; _nbAvailablePlugins = nbAvailablePlugins; _nbAvailableServices = nbAvailableServices; Debug.Assert( _nbTotalAvailablePlugins >= 1 ); _theOnlyPlugin = null; _theOnlyService = null; Array.Clear( _inclServices, 0, 10 ); Array.Clear( _exclServices, 0, 5 ); // Retrieves the potential only plugin. if( _nbTotalAvailablePlugins == 1 ) { if( _nbAvailablePlugins == 0 ) { ServiceData spec = Service.FirstSpecialization; while( spec != null ) { if( IsValidSpecialization( spec ) ) { BasePropagation propSpec = GetPropagationInfo( spec ); Debug.Assert( propSpec != null ); if( propSpec.TheOnlyPlugin != null ) { Debug.Assert( _theOnlyPlugin == null ); _theOnlyPlugin = propSpec.TheOnlyPlugin; } } spec = spec.NextSpecialization; } } else { PluginData p = Service.FirstPlugin; while( p != null ) { if( IsValidPlugin( p ) ) { Debug.Assert( _theOnlyPlugin == null ); _theOnlyPlugin = p; } p = p.NextPluginForService; } } Debug.Assert( _theOnlyPlugin != null && IsValidPlugin( _theOnlyPlugin ) ); } else if( _nbAvailablePlugins == 0 && _nbAvailableServices == 1 ) { ServiceData spec = Service.FirstSpecialization; while( spec != null ) { if( IsValidSpecialization( spec ) ) { Debug.Assert( _theOnlyService == null ); _theOnlyService = spec; } spec = spec.NextSpecialization; } Debug.Assert( _theOnlyService != null && IsValidSpecialization( _theOnlyService ) ); } Debug.Assert( (_nbTotalAvailablePlugins == 1) == (_theOnlyPlugin != null) ); }
internal bool IsGeneralizationOf(ServiceData d) { return(this == d || IsStrictGeneralizationOf(d)); }
protected override bool IsValidSpecialization( ServiceData s ) { return s.DynamicStatus == null || s.DynamicStatus.Value >= RunningStatus.Running; }
protected abstract BasePropagation GetPropagationInfo(ServiceData s);
public bool SetRunningService( ServiceData s, ServiceSolvedConfigStatusReason reason ) { Debug.Assert( s != null && s.Family == this ); if( s._configSolvedStatus != SolvedConfigurationStatus.Running ) { s._configSolvedStatus = SolvedConfigurationStatus.Running; s._configSolvedStatusReason = reason; } if( _runningService == s ) return !s.Disabled; if( s.Disabled ) return false; if( _runningService != null ) { // If there is already a current running service, we ONLY accept a more specialized // running service than the current one: if this service is not a specialization, we reject the change. if( !_runningService.IsStrictGeneralizationOf( s ) ) { ServiceDisabledReason r = Solver.Step == ConfigurationSolverStep.RegisterServices ? ServiceDisabledReason.AnotherServiceIsRunningByConfig : ServiceDisabledReason.AnotherServiceRunningInFamily; s.SetDisabled( r ); if( !Root.Disabled ) Root.SetDisabled( ServiceDisabledReason.AtLeastTwoSpecializationsMustRun ); return false; } } if( _runningPlugin != null ) { if( !s.IsGeneralizationOf( _runningPlugin.Service ) ) { s.SetDisabled( ServiceDisabledReason.PluginRunningElsewhere ); return false; } } // We first set a running configSolvedStatus from this service up to the root. // We do not propagate anything here since the most specialized service necessarily "contains" // the propagation of its ancestors. var g = s.Generalization; while( g != null ) { if( g._configSolvedStatus != SolvedConfigurationStatus.Running ) { g._configSolvedStatus = SolvedConfigurationStatus.Running; g._configSolvedStatusReason = ServiceSolvedConfigStatusReason.FromRunningSpecialization; } g = g.Generalization; } var prevRunningService = _runningService; _runningService = s; // We must now disable all sibling services (and plugins) from this up to the currently running one and // when the current one is null, up to the root. g = s.Generalization; var specRunning = s; while( g != null ) { var spec = g.FirstSpecialization; while( spec != null ) { if( spec != specRunning && !spec.Disabled ) spec.SetDisabled( ServiceDisabledReason.SiblingSpecializationRunning ); spec = spec.NextSpecialization; } PluginData p = g.FirstPlugin; while( p != null ) { if( !p.Disabled ) p.SetDisabled( PluginDisabledReason.ServiceSpecializationRunning ); p = p.NextPluginForService; } specRunning = g; g = g.Generalization; if( prevRunningService != null && g == prevRunningService.Generalization ) break; } return !s.Disabled; }
internal LiveServiceInfo( ServiceData s, YodiiEngine engine ) : base(engine, s, s.ServiceInfo.ServiceFullName) { _serviceInfo = s.ServiceInfo; }
public IEnumerable <ServiceData> GetIncludedServices(StartDependencyImpact impact, bool forRunnableStatus) { if (_theOnlyPlugin != null) { return(_theOnlyPlugin.GetIncludedServices(impact, forRunnableStatus)); } if (_theOnlyService != null) { return(GetPropagationInfo(_theOnlyService).GetIncludedServices(impact, forRunnableStatus)); } int iImpact = (int)impact; if (forRunnableStatus) { iImpact *= 2; } --iImpact; IEnumerable <ServiceData> inclExist = _inclServices[iImpact]; if (inclExist == null) { HashSet <ServiceData> incl = null; ServiceData spec = Service.FirstSpecialization; while (spec != null) { BasePropagation prop = GetPropagationInfo(spec); if (prop != null) { if (incl == null) { incl = new HashSet <ServiceData>(prop.GetIncludedServices(impact, forRunnableStatus)); } else { incl.IntersectWith(prop.GetIncludedServices(impact, forRunnableStatus)); } } spec = spec.NextSpecialization; } PluginData p = Service.FirstPlugin; while (p != null) { if (!p.Disabled) { if (incl == null) { incl = new HashSet <ServiceData>(p.GetIncludedServices(impact, forRunnableStatus)); } else { incl.IntersectWith(p.GetIncludedServices(impact, forRunnableStatus)); } } p = p.NextPluginForService; } _inclServices[iImpact] = inclExist = incl ?? Service.InheritedServicesWithThis; } return(inclExist); }
internal void UpdateFrom( ServiceData s, DelayedPropertyNotification notifier ) { UpdateItem( s, notifier ); notifier.Update( this, ref _serviceInfo, s.ServiceInfo, () => ServiceInfo ); }
protected void Refresh(int nbTotalAvalaiblePlugins, int nbAvailablePlugins, int nbAvailableServices) { if (_nbTotalAvailablePlugins == nbTotalAvalaiblePlugins && _nbAvailablePlugins == nbAvailablePlugins && _nbAvailableServices == nbAvailableServices) { return; } _nbTotalAvailablePlugins = nbTotalAvalaiblePlugins; _nbAvailablePlugins = nbAvailablePlugins; _nbAvailableServices = nbAvailableServices; Debug.Assert(_nbTotalAvailablePlugins >= 1); _theOnlyPlugin = null; _theOnlyService = null; Array.Clear(_inclServices, 0, 10); Array.Clear(_exclServices, 0, 5); // Retrieves the potential only plugin. if (_nbTotalAvailablePlugins == 1) { if (_nbAvailablePlugins == 0) { ServiceData spec = Service.FirstSpecialization; while (spec != null) { if (IsValidSpecialization(spec)) { BasePropagation propSpec = GetPropagationInfo(spec); Debug.Assert(propSpec != null); if (propSpec.TheOnlyPlugin != null) { Debug.Assert(_theOnlyPlugin == null); _theOnlyPlugin = propSpec.TheOnlyPlugin; } } spec = spec.NextSpecialization; } } else { PluginData p = Service.FirstPlugin; while (p != null) { if (IsValidPlugin(p)) { Debug.Assert(_theOnlyPlugin == null); _theOnlyPlugin = p; } p = p.NextPluginForService; } } Debug.Assert(_theOnlyPlugin != null && IsValidPlugin(_theOnlyPlugin)); } else if (_nbAvailablePlugins == 0 && _nbAvailableServices == 1) { ServiceData spec = Service.FirstSpecialization; while (spec != null) { if (IsValidSpecialization(spec)) { Debug.Assert(_theOnlyService == null); _theOnlyService = spec; } spec = spec.NextSpecialization; } Debug.Assert(_theOnlyService != null && IsValidSpecialization(_theOnlyService)); } Debug.Assert((_nbTotalAvailablePlugins == 1) == (_theOnlyPlugin != null)); }
protected abstract bool IsValidSpecialization( ServiceData s );
void IConfigurationSolver.DeferPropagation( ServiceData s ) { _deferedPropagation.Add( s ); }
ServiceData RegisterService( FinalConfiguration finalConfig, IServiceInfo s ) { ServiceData data; if( _services.TryGetValue( s.ServiceFullName, out data ) ) return data; //Set default status ConfigurationStatus serviceStatus = finalConfig.GetStatus( s.ServiceFullName ); // Handle generalization. ServiceData dataGen = null; if( s.Generalization != null ) { dataGen = RegisterService( finalConfig, s.Generalization ); } Debug.Assert( (s.Generalization == null) == (dataGen == null) ); if( dataGen == null ) { data = new ServiceData( this, s, serviceStatus ); _serviceFamilies.Add( data.Family ); } else { data = new ServiceData( s, dataGen, serviceStatus ); } _services.Add( s.ServiceFullName, data ); return data; }
public ServiceFamily(IConfigurationSolver solver, ServiceData root) { Solver = solver; Root = root; _availableServices = new HashSet <ServiceData>(); }
public bool SetRunningService(ServiceData s, ServiceSolvedConfigStatusReason reason) { Debug.Assert(s != null && s.Family == this); if (s._configSolvedStatus != SolvedConfigurationStatus.Running) { s._configSolvedStatus = SolvedConfigurationStatus.Running; s._configSolvedStatusReason = reason; } if (_runningService == s) { return(!s.Disabled); } if (s.Disabled) { return(false); } if (_runningService != null) { // If there is already a current running service, we ONLY accept a more specialized // running service than the current one: if this service is not a specialization, we reject the change. if (!_runningService.IsStrictGeneralizationOf(s)) { ServiceDisabledReason r = Solver.Step == ConfigurationSolverStep.RegisterServices ? ServiceDisabledReason.AnotherServiceIsRunningByConfig : ServiceDisabledReason.AnotherServiceRunningInFamily; s.SetDisabled(r); if (!Root.Disabled) { Root.SetDisabled(ServiceDisabledReason.AtLeastTwoSpecializationsMustRun); } return(false); } } if (_runningPlugin != null) { if (!s.IsGeneralizationOf(_runningPlugin.Service)) { s.SetDisabled(ServiceDisabledReason.PluginRunningElsewhere); return(false); } } // We first set a running configSolvedStatus from this service up to the root. // We do not propagate anything here since the most specialized service necessarily "contains" // the propagation of its ancestors. var g = s.Generalization; while (g != null) { if (g._configSolvedStatus != SolvedConfigurationStatus.Running) { g._configSolvedStatus = SolvedConfigurationStatus.Running; g._configSolvedStatusReason = ServiceSolvedConfigStatusReason.FromRunningSpecialization; } g = g.Generalization; } var prevRunningService = _runningService; _runningService = s; // We must now disable all sibling services (and plugins) from this up to the currently running one and // when the current one is null, up to the root. g = s.Generalization; var specRunning = s; while (g != null) { var spec = g.FirstSpecialization; while (spec != null) { if (spec != specRunning && !spec.Disabled) { spec.SetDisabled(ServiceDisabledReason.SiblingSpecializationRunning); } spec = spec.NextSpecialization; } PluginData p = g.FirstPlugin; while (p != null) { if (!p.Disabled) { p.SetDisabled(PluginDisabledReason.ServiceSpecializationRunning); } p = p.NextPluginForService; } specRunning = g; g = g.Generalization; if (prevRunningService != null && g == prevRunningService.Generalization) { break; } } return(!s.Disabled); }
public StaticPropagation(ServiceData s) : base(s) { }
internal ServiceData( IServiceInfo s, ServiceData generalization, ConfigurationStatus serviceStatus, StartDependencyImpact impact = StartDependencyImpact.Unknown ) : this(s, serviceStatus, impact) { Family = generalization.Family; _inheritedServicesWithThis = new ServiceData[generalization._inheritedServicesWithThis.Length + 1]; generalization._inheritedServicesWithThis.CopyTo( _inheritedServicesWithThis, 0 ); _inheritedServicesWithThis[_inheritedServicesWithThis.Length - 1] = this; Generalization = generalization; NextSpecialization = Generalization.FirstSpecialization; Generalization.FirstSpecialization = this; Initialize(); if( !Disabled ) for( int i = 0; i < _inheritedServicesWithThis.Length - 1; ++i ) ++_inheritedServicesWithThis[i].AvailableServiceCount; }
public SolvedServiceSnapshot( ServiceData s ) : base(s) { _serviceInfo = s.ServiceInfo; }
internal bool IsGeneralizationOf( ServiceData d ) { return this == d || IsStrictGeneralizationOf( d ); }
protected override BasePropagation GetPropagationInfo(ServiceData s) { return(s.DynGetPropagationInfo()); }
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 ); } } }