// Scheduler returns a list of apps to sync for a given stage
Scheduler returns a list of apps to sync for a given stage
// Scheduler returns a list of apps to sync for a given stage
func Scheduler(log logr.Logger, apps []argov1alpha1.Application, stage syncv1alpha1.ProgressiveSyncStage, pss utils.ProgressiveSyncState) []argov1alpha1.Application {
	log = log.WithName("scheduler")
	var scheduledApps []argov1alpha1.Application
	outOfSyncApps := utils.GetAppsBySyncStatusCode(apps, argov1alpha1.SyncStatusCodeOutOfSync)
	if len(outOfSyncApps) == 0 {
		return scheduledApps
	}
	log.Info("fetched out-of-sync apps", "apps", utils.GetAppsName(outOfSyncApps))
	syncedInCurrentStage := utils.GetSyncedAppsByStage(apps, stage, pss)
	log.Info("fetched synced-in-current-stage apps", "apps", utils.GetAppsName(syncedInCurrentStage))
	progressingApps := utils.GetAppsByHealthStatusCode(apps, health.HealthStatusProgressing)
	log.Info("fetched progressing apps", "apps", utils.GetAppsName(progressingApps))
	maxTargets := pss.GetMaxTargets(stage)
	maxParallel := pss.GetMaxParallel(stage)
	if maxTargets == len(syncedInCurrentStage) {
		return scheduledApps
	}
	p := maxParallel - len(progressingApps)
	if p > len(outOfSyncApps) {
		p = len(outOfSyncApps)
	}
	 maxTargets = 3
	 maxParallel = 3
	 outOfSyncApps = 4
	 syncedInCurrentStage = 2
	 progressingApps = 1
	 p = 2
	 Without the following logic we have p=2, so we would end up with a total of 4 applications synced in the stage
	if p+len(syncedInCurrentStage) > maxTargets {
		p = maxTargets - len(syncedInCurrentStage)
	}
	for i := 0; i < p; i++ {
		scheduledApps = append(scheduledApps, outOfSyncApps[i])
	}
	return scheduledApps
}
func Scheduler ( log logr . Logger , apps [ ] argov1alpha1 . Application , stage syncv1alpha1 . ProgressiveSyncStage , pss utils . ProgressiveSyncState ) [ ] argov1alpha1 . Application { log = log . WithName ( " " ) var scheduledApps [ ] argov1alpha1 . Application outOfSyncApps := utils . GetAppsBySyncStatusCode ( apps , argov1alpha1 . SyncStatusCodeOutOfSync ) if len ( outOfSyncApps ) == 0 { return scheduledApps } log . Info ( " " , " " , utils . GetAppsName ( outOfSyncApps ) ) syncedInCurrentStage := utils . GetSyncedAppsByStage ( apps , stage , pss ) log . Info ( " " , " " , utils . GetAppsName ( syncedInCurrentStage ) ) progressingApps := utils . GetAppsByHealthStatusCode ( apps , health . HealthStatusProgressing ) log . Info ( " " , " " , utils . GetAppsName ( progressingApps ) ) maxTargets := pss . GetMaxTargets ( stage ) maxParallel := pss . GetMaxParallel ( stage ) if maxTargets == len ( syncedInCurrentStage ) { return scheduledApps } p := maxParallel - len ( progressingApps ) if p > len ( outOfSyncApps ) { p = len ( outOfSyncApps ) } if p + len ( syncedInCurrentStage ) > maxTargets { p = maxTargets - len ( syncedInCurrentStage ) } for i := 0 ; i < p ; i ++ { scheduledApps = append ( scheduledApps , outOfSyncApps [ i ] ) } return scheduledApps }
Scheduler returns a list of apps to sync for a given stage
Scheduler returns a list of apps to sync for a given stage
/*
		The Scheduler takes:
			- a ProgressiveSyncStage object
			- the Applications selected with the clusters selector

		The Scheduler splits the Applications in the following groups:
			- OutOfSync Applications: those are the Applications to update during the stage.
			- syncedInCurrentStage Applications: those are Application that synced during the current stage. Those Applications count against the number of clusters to update.
			- progressingApps: those are Applications that are still in progress updating. Those Applications count against the number of clusters to update in parallel.

		Why does the Scheduler need an annotation?
		Consider the scenario where we have 5 Applications - 4 OutOfSync and 1 Synced - and a stage with maxTargets = 3.
		If we don't keep track on which stage the Application synced, we can't compute how many applications we have to update in the current stage.
		Without the annotation, it would be impossible for the scheduler to know if the Application synced at this stage - and so we have only 2 Applications left to sync.
	*/ // If there are no OutOfSync Applications, return // If we already synced the desired number of Applications, return // Because of eventual consistency, there might be a time where // maxParallel-len(progressingApps) might actually be greater than len(outOfSyncApps) // causing the runtime to panic // Consider the following scenario // // maxTargets = 3 // maxParallel = 3 // outOfSyncApps = 4 // syncedInCurrentStage = 2 // progressingApps = 1 // p = 2 // // Without the following logic we have p=2, so we would end up with a total of 4 applications synced in the stage