in pkg/scheduler/framework/frameworkutils.go [279:357]
func newSchedulingDecisionsFromBindings(
maxUnselectedClusterDecisionCount int,
notPicked ScoredClusters,
filtered []*filteredClusterWithStatus,
existing ...[]*placementv1beta1.ClusterResourceBinding,
) []placementv1beta1.ClusterDecision {
// Pre-allocate with a reasonable capacity.
newDecisions := make([]placementv1beta1.ClusterDecision, 0, maxUnselectedClusterDecisionCount)
// Track clusters that have been added to the decision list.
//
// This is to avoid duplicate entries in the decision list, caused by a rare occurrence
// where a cluster is picked before, but later loses its status as a matching (or most
// preferable) cluster (e.g., a label/cluster property change) under the evaluation
// of **the same** scheduling policy.
//
// Note that for such occurrences, we will honor the previously made decisions in an attempt
// to reduce fluctations.
seenClusters := make(map[string]bool)
// Build new scheduling decisions.
slotsLeft := clustersDecisionArrayLengthLimitInAPI
for _, bindingSet := range existing {
setLength := len(bindingSet)
for i := 0; i < setLength && i < slotsLeft; i++ {
newDecisions = append(newDecisions, bindingSet[i].Spec.ClusterDecision)
seenClusters[bindingSet[i].Spec.TargetCluster] = true
}
slotsLeft -= setLength
if slotsLeft <= 0 {
klog.V(2).InfoS("Reached API limit of cluster decision count; decisions off the limit will be discarded")
break
}
}
// Add decisions for clusters that have been scored, but are not picked, if there are still
// enough room.
for _, sc := range notPicked {
if slotsLeft == 0 || maxUnselectedClusterDecisionCount == 0 {
break
}
if seenClusters[sc.Cluster.Name] {
// Skip clusters that have been added to the decision list.
continue
}
newDecisions = append(newDecisions, placementv1beta1.ClusterDecision{
ClusterName: sc.Cluster.Name,
Selected: false,
ClusterScore: &placementv1beta1.ClusterScore{
AffinityScore: ptr.To(sc.Score.AffinityScore),
TopologySpreadScore: ptr.To(sc.Score.TopologySpreadScore),
},
Reason: fmt.Sprintf(notPickedByScoreReasonTemplate, sc.Cluster.Name, sc.Score.AffinityScore, sc.Score.TopologySpreadScore),
})
slotsLeft--
maxUnselectedClusterDecisionCount--
}
// Move some decisions from unbound clusters, if there are still enough room.
for i := 0; i < maxUnselectedClusterDecisionCount && i < len(filtered) && i < slotsLeft; i++ {
clusterWithStatus := filtered[i]
if _, ok := seenClusters[clusterWithStatus.cluster.Name]; ok {
// Skip clusters that have been added to the decision list.
continue
}
newDecisions = append(newDecisions, placementv1beta1.ClusterDecision{
ClusterName: clusterWithStatus.cluster.Name,
Selected: false,
Reason: clusterWithStatus.status.String(),
})
}
return newDecisions
}