/// <summary> /// Finds app def in a plan. Throws if failed. /// </summary> //[return: MaybeNull] public PlanApp FindAppInPlan(string planName, AppIdTuple id) { return(FindPlan(planName).FindApp(id)); }
public InvalidAppConfig(AppIdTuple id, string msg) : base(string.Format("Invalid app '{0}' config: '{1}'.", id, msg)) { this.id = id; this.msg = msg; }
/// <summary> /// Builds the list of waves as the result of application interdependencies. /// /// The first wawe will contain apps that do not depend on any other app. /// The second wave will contain the apps that depend on those from the first wave. /// Etc. untill all apps are processed. /// </summary> List<AppWave> BuildLaunchWaves() { // seznam zbyvajicich aplikaci // seznam uz pouzitych aplikaci (ktere uz byly vlozeny do vln) // Prochazim seznam zbylych aplikaci a pro kazdou hledam, zda vsechny jeji zavislosti uz se nachazi // v seznamu pouzitych aplikaci. Pokud ano, zkopiruju aplikaci do aktualni vlny. Pro projiti // vsech aplikaci pak vezmu aplikace z aktulne vytvorene vlny, smazu je ze zbyvajicich a vlozim do pouzitych. List<PlanApp> remaining = (from t in _plan.Apps where !t.Def.Disabled select t).ToList(); // those not yet moved to any of the waves List<PlanApp> used = new(); // those already moved to some of waves // allow fast lookup of appdef by its name Dictionary<AppIdTuple, PlanApp> dictApps = new(); foreach (var app in remaining) { dictApps[app.Def.Id] = app; } var waves = new List<AppWave>(); // the resulting list of waves // For each of the remaining apps check whether all its dependencias were already moved to some of prevoiusly // built waves; if so, add the app to the current wave and move it from remaining to used. while (remaining.Count > 0) { List<PlanApp> currentWave = new(); // the wave currently being built foreach (var app in remaining) { var ad = app.Def; bool allDepsSatisfied = true; if (ad.Dependencies != null) { foreach (var depName in ad.Dependencies) { AppIdTuple depId = AppIdTuple.fromString(depName, ad.Id.MachineId); if( dictApps.TryGetValue( depId, out var dep ) ) // dependency found in the plan { if( !used.Contains(dep) ) // but not yet placed to any previous wave { allDepsSatisfied = false; // meaning it can't be satisfied and we shall NOT try to run it in this wave break; } } } } if (allDepsSatisfied) { currentWave.Add(app); } } if( currentWave.Count > 0 ) { // move apps that were added to the current wave from remaining to used foreach (var app in currentWave) { remaining.Remove(app); used.Add(app); } // add current wave to the resulting list of wawes waves.Add(new AppWave( currentWave ) ); } else { // circular dependency??? log.Warn($" {_plan.Name}: Can't build launch wave, perhaps circular dependency?"); break; } } for( int i=0; i < waves.Count; i++ ) { var w = waves[i]; log.Debug($"Launch wave #{i}: {string.Join(", ", from app in w.Apps select app.Def.Id)}"); } return waves; }
public NotALocalApp(AppIdTuple id, string localMachineId) : base(String.Format("App '{0}' not defined for machine '{1}'", id, localMachineId)) { this.id = id; }
public UnknownAppInPlanException(AppIdTuple id, string planName) : base($"{id} not found in plan {planName}") { this.id = id; this.planName = planName; }
public UnknownAppIdException(AppIdTuple appIdTuple) : base("AppId '" + appIdTuple.MachineId + "." + appIdTuple.AppId + "' not found.") { this.appIdTuple = appIdTuple; }
public bool Equals(AppIdTuple p) { // Return true if the fields match: return((MachineId == p.MachineId) && (AppId == p.AppId)); }
public void AddOrUpdate(AppIdTuple id, AppState appState) { _appStates[id] = appState; }