예제 #1
0
 /// <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));
 }
예제 #2
0
 public InvalidAppConfig(AppIdTuple id, string msg)
     : base(string.Format("Invalid app '{0}' config: '{1}'.", id, msg))
 {
     this.id  = id;
     this.msg = msg;
 }
예제 #3
0
        /// <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;
        }
예제 #4
0
 public NotALocalApp(AppIdTuple id, string localMachineId)
     : base(String.Format("App '{0}' not defined for machine '{1}'", id, localMachineId))
 {
     this.id = id;
 }
예제 #5
0
 public UnknownAppInPlanException(AppIdTuple id, string planName)
     : base($"{id} not found in plan {planName}")
 {
     this.id       = id;
     this.planName = planName;
 }
예제 #6
0
 public UnknownAppIdException(AppIdTuple appIdTuple)
     : base("AppId '" + appIdTuple.MachineId + "." + appIdTuple.AppId + "' not found.")
 {
     this.appIdTuple = appIdTuple;
 }
예제 #7
0
 public bool Equals(AppIdTuple p)
 {
     // Return true if the fields match:
     return((MachineId == p.MachineId) && (AppId == p.AppId));
 }
예제 #8
0
 public void AddOrUpdate(AppIdTuple id, AppState appState)
 {
     _appStates[id] = appState;
 }