示例#1
0
        bool AreAllDepsSatisfied( AppDef appDef )
        {
            // pokud jsou vsechny aplikace na kterych ta nase zavisi spousteny
            bool allDepsSatisfied = true;

            if (appDef.Dependencies != null)
            {
                foreach (var depName in appDef.Dependencies)
                {
                    AppIdTuple depId = AppIdTuple.fromString(depName, appDef.Id.MachineId);

                    if (!_appsState.ContainsKey(depId))
                    {
                        // throw exception "Unknown dependency"
                        throw new UnknownDependencyException(depName);
                    }

                    var dep = _appsState[depId];
                    if (!dep.Initialized)
                    {
                        allDepsSatisfied = false;
                        break;
                    }

                }
            }
            return allDepsSatisfied;
        }
示例#2
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;
        }