@@ -12,6 +12,7 @@ import (
12
12
"github.com/karmada-io/karmada/pkg/scheduler/cache"
13
13
"github.com/karmada-io/karmada/pkg/scheduler/framework"
14
14
"github.com/karmada-io/karmada/pkg/scheduler/framework/runtime"
15
+ "github.com/karmada-io/karmada/pkg/util"
15
16
)
16
17
17
18
// ScheduleAlgorithm is the interface that should be implemented to schedule a resource to the target clusters.
@@ -81,7 +82,7 @@ func (g *genericScheduler) Schedule(ctx context.Context, binding *v1alpha1.Propa
81
82
}
82
83
klog .V (4 ).Infof ("feasible clusters scores for <%s/%s>: %v" , binding .Namespace , binding .Name , clustersScore )
83
84
84
- clusters := g .selectClusters (clustersScore )
85
+ clusters := g .selectClusters (clustersScore , policy . Spec . Placement . SpreadConstraints , feasibleClusters )
85
86
result .SuggestedClusters = clusters
86
87
87
88
return result , nil
@@ -130,11 +131,76 @@ func (g *genericScheduler) prioritizeClusters(
130
131
return result , nil
131
132
}
132
133
133
- // TODO: update the algorithms
134
- func (g * genericScheduler ) selectClusters (clustersScore framework.ClusterScoreList ) []string {
134
+ func (g * genericScheduler ) selectClusters (clustersScore framework.ClusterScoreList , spreadConstraints []v1alpha1.SpreadConstraint , clusters []* clusterapi.Cluster ) []string {
135
+ if len (spreadConstraints ) != 0 {
136
+ return g .matchSpreadConstraints (clusters , spreadConstraints )
137
+ }
138
+
135
139
out := make ([]string , len (clustersScore ))
136
140
for i := range clustersScore {
137
141
out [i ] = clustersScore [i ].Name
138
142
}
139
143
return out
140
144
}
145
+
146
+ func (g * genericScheduler ) matchSpreadConstraints (clusters []* clusterapi.Cluster , spreadConstraints []v1alpha1.SpreadConstraint ) []string {
147
+ state := util .NewSpreadGroup ()
148
+ g .runSpreadConstraintsFilter (clusters , spreadConstraints , state )
149
+ return g .calSpreadResult (state )
150
+ }
151
+
152
+ // Now support spread by cluster. More rules will be implemented later.
153
+ func (g * genericScheduler ) runSpreadConstraintsFilter (clusters []* clusterapi.Cluster , spreadConstraints []v1alpha1.SpreadConstraint , spreadGroup * util.SpreadGroup ) {
154
+ for _ , spreadConstraint := range spreadConstraints {
155
+ spreadGroup .InitialGroupRecord (spreadConstraint )
156
+ if spreadConstraint .SpreadByField == v1alpha1 .SpreadByFieldCluster {
157
+ g .groupByFieldCluster (clusters , spreadConstraint , spreadGroup )
158
+ }
159
+ }
160
+ }
161
+
162
+ func (g * genericScheduler ) groupByFieldCluster (clusters []* clusterapi.Cluster , spreadConstraint v1alpha1.SpreadConstraint , spreadGroup * util.SpreadGroup ) {
163
+ for _ , cluster := range clusters {
164
+ clusterGroup := cluster .Name
165
+ spreadGroup.GroupRecord [spreadConstraint ][clusterGroup ] = append (spreadGroup.GroupRecord [spreadConstraint ][clusterGroup ], cluster .Name )
166
+ }
167
+ }
168
+
169
+ func (g * genericScheduler ) calSpreadResult (spreadGroup * util.SpreadGroup ) []string {
170
+ // TODO: now support single spread constraint
171
+ if len (spreadGroup .GroupRecord ) > 1 {
172
+ return nil
173
+ }
174
+
175
+ return g .chooseSpreadGroup (spreadGroup )
176
+ }
177
+
178
+ func (g * genericScheduler ) chooseSpreadGroup (spreadGroup * util.SpreadGroup ) []string {
179
+ var feasibleClusters []string
180
+ for spreadConstraint , clusterGroups := range spreadGroup .GroupRecord {
181
+ if spreadConstraint .SpreadByField == v1alpha1 .SpreadByFieldCluster {
182
+ if len (clusterGroups ) < spreadConstraint .MinGroups {
183
+ return nil
184
+ }
185
+
186
+ if len (clusterGroups ) <= spreadConstraint .MaxGroups {
187
+ for _ , v := range clusterGroups {
188
+ feasibleClusters = append (feasibleClusters , v ... )
189
+ }
190
+ break
191
+ }
192
+
193
+ if spreadConstraint .MaxGroups > 0 && len (clusterGroups ) > spreadConstraint .MaxGroups {
194
+ var groups []string
195
+ for group := range clusterGroups {
196
+ groups = append (groups , group )
197
+ }
198
+
199
+ for i := 0 ; i < spreadConstraint .MaxGroups ; i ++ {
200
+ feasibleClusters = append (feasibleClusters , clusterGroups [groups [i ]]... )
201
+ }
202
+ }
203
+ }
204
+ }
205
+ return feasibleClusters
206
+ }
0 commit comments