@@ -108,6 +108,7 @@ func (e *BinpackingNodeEstimator) Estimate(
108
108
}()
109
109
110
110
estimationState := newEstimationState ()
111
+ newNodesAvailable := true
111
112
for _ , podsEquivalenceGroup := range podsEquivalenceGroups {
112
113
var err error
113
114
var remainingPods []* apiv1.Pod
@@ -118,10 +119,12 @@ func (e *BinpackingNodeEstimator) Estimate(
118
119
return 0 , nil
119
120
}
120
121
121
- err = e .tryToScheduleOnNewNodes (estimationState , nodeTemplate , remainingPods )
122
- if err != nil {
123
- klog .Error (err .Error ())
124
- return 0 , nil
122
+ if newNodesAvailable {
123
+ newNodesAvailable , err = e .tryToScheduleOnNewNodes (estimationState , nodeTemplate , remainingPods )
124
+ if err != nil {
125
+ klog .Error (err .Error ())
126
+ return 0 , nil
127
+ }
125
128
}
126
129
}
127
130
@@ -156,11 +159,13 @@ func (e *BinpackingNodeEstimator) tryToScheduleOnExistingNodes(
156
159
return pods [index :], nil
157
160
}
158
161
162
+ // Returns whether it is worth retrying adding new nodes and error in unexpected
163
+ // situations where whole estimation should be stopped.
159
164
func (e * BinpackingNodeEstimator ) tryToScheduleOnNewNodes (
160
165
estimationState * estimationState ,
161
166
nodeTemplate * framework.NodeInfo ,
162
167
pods []* apiv1.Pod ,
163
- ) error {
168
+ ) ( bool , error ) {
164
169
for _ , pod := range pods {
165
170
found := false
166
171
@@ -172,7 +177,7 @@ func (e *BinpackingNodeEstimator) tryToScheduleOnNewNodes(
172
177
estimationState .trackScheduledPod (pod , estimationState .lastNodeName )
173
178
} else if err .Type () == clustersnapshot .SchedulingInternalError {
174
179
// Unexpected error.
175
- return err
180
+ return false , err
176
181
}
177
182
// The pod can't be scheduled on the newly created node because of scheduling predicates.
178
183
}
@@ -182,7 +187,7 @@ func (e *BinpackingNodeEstimator) tryToScheduleOnNewNodes(
182
187
// on a new node either. There is no point adding more nodes to snapshot in such case, especially because of
183
188
// performance cost each extra node adds to future FitsAnyNodeMatching calls.
184
189
if estimationState .lastNodeName != "" && ! estimationState .newNodesWithPods [estimationState .lastNodeName ] {
185
- break
190
+ return true , nil
186
191
}
187
192
188
193
// Stop binpacking if we reach the limit of nodes we can add.
@@ -192,12 +197,12 @@ func (e *BinpackingNodeEstimator) tryToScheduleOnNewNodes(
192
197
// each call that returns true, one node gets added. Therefore this
193
198
// must be the last check right before really adding a node.
194
199
if ! e .limiter .PermissionToAddNode () {
195
- break
200
+ return false , nil
196
201
}
197
202
198
203
// Add new node
199
204
if err := e .addNewNodeToSnapshot (estimationState , nodeTemplate ); err != nil {
200
- return fmt .Errorf ("Error while adding new node for template to ClusterSnapshot; %w" , err )
205
+ return false , fmt .Errorf ("Error while adding new node for template to ClusterSnapshot; %w" , err )
201
206
}
202
207
203
208
// And try to schedule pod to it.
@@ -206,7 +211,7 @@ func (e *BinpackingNodeEstimator) tryToScheduleOnNewNodes(
206
211
// adding and removing node to snapshot for each such pod.
207
212
if err := e .clusterSnapshot .SchedulePod (pod , estimationState .lastNodeName ); err != nil && err .Type () == clustersnapshot .SchedulingInternalError {
208
213
// Unexpected error.
209
- return err
214
+ return false , err
210
215
} else if err != nil {
211
216
// The pod can't be scheduled on the new node because of scheduling predicates.
212
217
break
@@ -215,7 +220,7 @@ func (e *BinpackingNodeEstimator) tryToScheduleOnNewNodes(
215
220
estimationState .trackScheduledPod (pod , estimationState .lastNodeName )
216
221
}
217
222
}
218
- return nil
223
+ return true , nil
219
224
}
220
225
221
226
func (e * BinpackingNodeEstimator ) addNewNodeToSnapshot (
0 commit comments