@@ -133,6 +133,8 @@ func init() {
133
133
134
134
// For more details, check Reconcile and its Result here:
135
135
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.4/pkg/reconcile
136
+ //
137
+ //nolint:gocyclo
136
138
func (r * MostWantedTwoPhaseHysteresisEvaluationReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (ctrl.Result , error ) {
137
139
log := log .FromContext (ctx )
138
140
log .V (2 ).Info ("Received reconcile request" )
@@ -202,12 +204,12 @@ func (r *MostWantedTwoPhaseHysteresisEvaluationReconciler) Reconcile(ctx context
202
204
return ctrl.Result {}, nil
203
205
}
204
206
205
- replicas := partitionProvider .GetPartitionProviderStatus ().Replicas
206
- log .V (2 ).Info ("Currently reported replicas by partition provider" , "count" , len (replicas ))
207
+ currentReplicas := partitionProvider .GetPartitionProviderStatus ().Replicas
208
+ log .V (2 ).Info ("Currently reported replicas by partition provider" , "count" , len (currentReplicas ))
207
209
208
210
seenBefore := false
209
211
for i , record := range evaluation .Status .History {
210
- if record .Replicas . SerializeToString () == replicas .SerializeToString () {
212
+ if record .ReplicasHash == Sha256 ( currentReplicas .SerializeToString () ) {
211
213
seenBefore = true
212
214
evaluation .Status .History [i ].SeenTimes ++
213
215
evaluation .Status .History [i ].Timestamp = metav1 .Now ()
@@ -217,9 +219,9 @@ func (r *MostWantedTwoPhaseHysteresisEvaluationReconciler) Reconcile(ctx context
217
219
if ! seenBefore {
218
220
evaluation .Status .History = append (evaluation .Status .History ,
219
221
autoscalerv1alpha1.MostWantedTwoPhaseHysteresisEvaluationStatusHistoricalRecord {
220
- Timestamp : metav1 .Now (),
221
- Replicas : replicas ,
222
- SeenTimes : 1 ,
222
+ Timestamp : metav1 .Now (),
223
+ ReplicasHash : Sha256 ( currentReplicas . SerializeToString ()) ,
224
+ SeenTimes : 1 ,
223
225
},
224
226
)
225
227
}
@@ -237,45 +239,65 @@ func (r *MostWantedTwoPhaseHysteresisEvaluationReconciler) Reconcile(ctx context
237
239
evaluation .Status .History = cleanHistory
238
240
}
239
241
240
- historyRecords := map [string ]autoscalerv1alpha1.MostWantedTwoPhaseHysteresisEvaluationStatusHistoricalRecord {}
241
- historyRecordsLastSeen := map [string ]metav1.Time {}
242
- historyRecorsSeenTimes := map [string ]int32 {}
242
+ historyRecordsByHash := map [string ]autoscalerv1alpha1.MostWantedTwoPhaseHysteresisEvaluationStatusHistoricalRecord {}
243
+ historyRecordsByHashLastSeen := map [string ]metav1.Time {}
244
+ historyRecorsByHashSeenTimes := map [string ]int32 {}
243
245
for _ , record := range evaluation .Status .History {
244
- serializedRecord := record .Replicas . SerializeToString ()
245
- log .V (2 ).Info ("Noticing record" , "record" , serializedRecord )
246
- if _ , ok := historyRecordsLastSeen [ serializedRecord ]; ! ok {
247
- historyRecords [ serializedRecord ] = record
248
- historyRecordsLastSeen [ serializedRecord ] = record .Timestamp
249
- historyRecorsSeenTimes [ serializedRecord ] = record .SeenTimes
250
- } else if record .Timestamp .After (historyRecordsLastSeen [ serializedRecord ].Time ) {
251
- historyRecordsLastSeen [ serializedRecord ] = record .Timestamp
252
- historyRecorsSeenTimes [ serializedRecord ] += record .SeenTimes
246
+ hash := record .ReplicasHash
247
+ log .V (2 ).Info ("Noticing record" , "record" , hash )
248
+ if _ , ok := historyRecordsByHashLastSeen [ hash ]; ! ok {
249
+ historyRecordsByHash [ hash ] = record
250
+ historyRecordsByHashLastSeen [ hash ] = record .Timestamp
251
+ historyRecorsByHashSeenTimes [ hash ] = record .SeenTimes
252
+ } else if record .Timestamp .After (historyRecordsByHashLastSeen [ hash ].Time ) {
253
+ historyRecordsByHashLastSeen [ hash ] = record .Timestamp
254
+ historyRecorsByHashSeenTimes [ hash ] += record .SeenTimes
253
255
} else {
254
- historyRecorsSeenTimes [ serializedRecord ] += record .SeenTimes
256
+ historyRecorsByHashSeenTimes [ hash ] += record .SeenTimes
255
257
}
256
258
}
257
259
258
260
topSeenRecord := autoscalerv1alpha1.MostWantedTwoPhaseHysteresisEvaluationStatusHistoricalRecord {}
259
261
maxSeenCount := int32 (0 )
260
- for serializedRecord , seenTimes := range historyRecorsSeenTimes {
261
- log .V (2 ).Info ("Evaluating records" , "record" , serializedRecord , "seenTimes" , seenTimes )
262
+ for hash , seenTimes := range historyRecorsByHashSeenTimes {
263
+ log .V (2 ).Info ("Evaluating records" , "record" , hash , "seenTimes" , seenTimes )
262
264
if seenTimes > maxSeenCount {
263
265
maxSeenCount = seenTimes
264
- topSeenRecord = historyRecords [ serializedRecord ]
266
+ topSeenRecord = historyRecordsByHash [ hash ]
265
267
} else if seenTimes == maxSeenCount &&
266
- historyRecords [ serializedRecord ].Timestamp .After (topSeenRecord .Timestamp .Time ) {
267
- log .V (2 ).Info ("Tie breaker" , "left" , topSeenRecord , "right" , serializedRecord )
268
- topSeenRecord = historyRecords [ serializedRecord ]
268
+ historyRecordsByHash [ hash ].Timestamp .After (topSeenRecord .Timestamp .Time ) {
269
+ log .V (2 ).Info ("Tie breaker" , "left" , topSeenRecord . ReplicasHash , "right" , hash )
270
+ topSeenRecord = historyRecordsByHash [ hash ]
269
271
}
270
272
}
271
- log .V (2 ).Info ("Top seen record" , "record" , topSeenRecord .Replicas .SerializeToString ())
273
+ log .V (2 ).Info ("Top seen record" , "record" , topSeenRecord .ReplicasHash )
274
+ if topSeenRecord .ReplicasHash == Sha256 (currentReplicas .SerializeToString ()) {
275
+ log .V (1 ).Info ("A new election projection updated" , "record" , topSeenRecord .ReplicasHash )
276
+ evaluation .Status .Projection = currentReplicas
277
+ }
278
+ if topSeenRecord .ReplicasHash != Sha256 (evaluation .Status .Projection .SerializeToString ()) {
279
+ err := fmt .Errorf ("top seen record is neither current projection nor current partition" )
280
+ log .Error (err , "Failed to evaluate" )
281
+ meta .SetStatusCondition (& evaluation .Status .Conditions , metav1.Condition {
282
+ Type : StatusTypeReady ,
283
+ Status : metav1 .ConditionFalse ,
284
+ Reason : "AwaitingNewProjection" ,
285
+ Message : err .Error (),
286
+ })
287
+ if err := r .Status ().Update (ctx , evaluation ); err != nil {
288
+ log .V (1 ).Info ("Failed to update resource status" , "err" , err )
289
+ return ctrl.Result {}, err
290
+ }
291
+ // In this case re-queuing will change nothing
292
+ return ctrl.Result {}, nil
293
+ }
272
294
mostWantedTwoPhaseHysteresisEvaluationProjectedShardsGauge .DeletePartialMatch (prometheus.Labels {
273
295
"evaluation_ref" : req .NamespacedName .String (),
274
296
})
275
297
mostWantedTwoPhaseHysteresisEvaluationProjectedReplicasTotalLoadGauge .DeletePartialMatch (prometheus.Labels {
276
298
"evaluation_ref" : req .NamespacedName .String (),
277
299
})
278
- for _ , replica := range topSeenRecord . Replicas {
300
+ for _ , replica := range evaluation . Status . Projection {
279
301
for _ , li := range replica .LoadIndexes {
280
302
mostWantedTwoPhaseHysteresisEvaluationProjectedShardsGauge .WithLabelValues (
281
303
req .NamespacedName .String (),
@@ -293,10 +315,9 @@ func (r *MostWantedTwoPhaseHysteresisEvaluationReconciler) Reconcile(ctx context
293
315
).Set (replica .TotalLoad .AsApproximateFloat64 ())
294
316
}
295
317
296
- evaluation .Status .Projection = topSeenRecord .Replicas
297
318
if evaluation .Status .LastEvaluationTimestamp == nil ||
298
319
time .Since (evaluation .Status .LastEvaluationTimestamp .Time ) >= evaluation .Spec .StabilizationPeriod .Duration {
299
- evaluation .Status .Replicas = topSeenRecord . Replicas
320
+ evaluation .Status .Replicas = evaluation . Status . Projection
300
321
evaluation .Status .LastEvaluationTimestamp = ptr .To (metav1 .Now ())
301
322
log .Info ("New partitioning has won" ,
302
323
"replicas" , len (evaluation .Status .Replicas ), "lastEvaluationTimestamp" , evaluation .Status .LastEvaluationTimestamp )
0 commit comments