Skip to content

Commit e2aab87

Browse files
authored
fix: Requeue immediately after status update conflict (#1589)
Signed-off-by: drivebyer <[email protected]>
1 parent 96c48f5 commit e2aab87

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

internal/controller/rediscluster/rediscluster_controller.go

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
133133
// Mark the cluster status as initializing if there are no leader or follower nodes
134134
if (instance.Status.ReadyLeaderReplicas == 0 && instance.Status.ReadyFollowerReplicas == 0) ||
135135
instance.Status.ReadyLeaderReplicas != leaderReplicas {
136-
err = r.updateStatus(ctx, instance, rcvb2.RedisClusterStatus{
136+
requeue, err := r.updateStatus(ctx, instance, rcvb2.RedisClusterStatus{
137137
State: rcvb2.RedisClusterInitializing,
138138
Reason: rcvb2.InitializingClusterLeaderReason,
139139
ReadyLeaderReplicas: instance.Status.ReadyLeaderReplicas,
@@ -142,6 +142,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
142142
if err != nil {
143143
return intctrlutil.RequeueE(ctx, err, "")
144144
}
145+
if requeue {
146+
return intctrlutil.Requeue()
147+
}
145148
}
146149

147150
err = k8sutils.CreateRedisLeader(ctx, instance, r.K8sClient)
@@ -164,7 +167,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
164167
// Mark the cluster status as initializing if there are no follower nodes
165168
if (instance.Status.ReadyLeaderReplicas == 0 && instance.Status.ReadyFollowerReplicas == 0) ||
166169
instance.Status.ReadyFollowerReplicas != followerReplicas {
167-
err = r.updateStatus(ctx, instance, rcvb2.RedisClusterStatus{
170+
requeue, err := r.updateStatus(ctx, instance, rcvb2.RedisClusterStatus{
168171
State: rcvb2.RedisClusterInitializing,
169172
Reason: rcvb2.InitializingClusterFollowerReason,
170173
ReadyLeaderReplicas: leaderReplicas,
@@ -173,6 +176,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
173176
if err != nil {
174177
return intctrlutil.RequeueE(ctx, err, "")
175178
}
179+
if requeue {
180+
return intctrlutil.Requeue()
181+
}
176182
}
177183
// if we have followers create their service.
178184
if followerReplicas != 0 {
@@ -197,7 +203,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
197203

198204
// Mark the cluster status as bootstrapping if all the leader and follower nodes are ready
199205
if instance.Status.ReadyLeaderReplicas != leaderReplicas || instance.Status.ReadyFollowerReplicas != followerReplicas {
200-
err = r.updateStatus(ctx, instance, rcvb2.RedisClusterStatus{
206+
requeue, err := r.updateStatus(ctx, instance, rcvb2.RedisClusterStatus{
201207
State: rcvb2.RedisClusterBootstrap,
202208
Reason: rcvb2.BootstrapClusterReason,
203209
ReadyLeaderReplicas: leaderReplicas,
@@ -206,6 +212,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
206212
if err != nil {
207213
return intctrlutil.RequeueE(ctx, err, "")
208214
}
215+
if requeue {
216+
return intctrlutil.Requeue()
217+
}
209218
}
210219

211220
// When the number of leader replicas is 1 (single-node cluster)
@@ -255,7 +264,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
255264
logger.Error(err, "failed to determine unhealthy node count in cluster")
256265
}
257266
if int(totalReplicas) > 1 && unhealthyNodeCount > 0 {
258-
err = r.updateStatus(ctx, instance, rcvb2.RedisClusterStatus{
267+
requeue, err := r.updateStatus(ctx, instance, rcvb2.RedisClusterStatus{
259268
State: rcvb2.RedisClusterFailed,
260269
Reason: "RedisCluster has unhealthy nodes",
261270
ReadyLeaderReplicas: leaderReplicas,
@@ -264,6 +273,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
264273
if err != nil {
265274
return intctrlutil.RequeueE(ctx, err, "")
266275
}
276+
if requeue {
277+
return intctrlutil.Requeue()
278+
}
267279

268280
logger.Info("healthy leader count does not match desired; attempting to repair disconnected masters")
269281
if err = k8sutils.RepairDisconnectedMasters(ctx, r.K8sClient, instance); err != nil {
@@ -312,7 +324,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
312324
return intctrlutil.RequeueE(ctx, err, "failed to set dynamic config")
313325
}
314326

315-
err = r.updateStatus(ctx, instance, rcvb2.RedisClusterStatus{
327+
requeue, err := r.updateStatus(ctx, instance, rcvb2.RedisClusterStatus{
316328
State: rcvb2.RedisClusterReady,
317329
Reason: rcvb2.ReadyClusterReason,
318330
ReadyLeaderReplicas: leaderReplicas,
@@ -321,6 +333,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
321333
if err != nil {
322334
return intctrlutil.RequeueE(ctx, err, "")
323335
}
336+
if requeue {
337+
return intctrlutil.Requeue()
338+
}
324339
}
325340
}
326341

@@ -334,29 +349,29 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
334349
return intctrlutil.RequeueAfter(ctx, time.Second*10, "")
335350
}
336351

337-
func (r *Reconciler) updateStatus(ctx context.Context, rc *rcvb2.RedisCluster, status rcvb2.RedisClusterStatus) error {
352+
func (r *Reconciler) updateStatus(ctx context.Context, rc *rcvb2.RedisCluster, status rcvb2.RedisClusterStatus) (requeue bool, err error) {
338353
if reflect.DeepEqual(rc.Status, status) {
339-
return nil
354+
return false, nil
340355
}
341356
copy := rc.DeepCopy()
342357
copy.Spec = rcvb2.RedisClusterSpec{}
343358
copy.Status = status
344-
err := common.UpdateStatus(ctx, r.Client, copy)
359+
err = common.UpdateStatus(ctx, r.Client, copy)
345360
if err != nil && apierrors.IsConflict(err) {
346361
log.FromContext(ctx).Info("conflict detected, reloading instance and retrying status update")
347362
namespacedName := client.ObjectKey{
348363
Namespace: rc.Namespace,
349364
Name: rc.Name,
350365
}
351366
if err := r.Get(ctx, namespacedName, rc); err != nil {
352-
return err
367+
return true, err
353368
}
354369
copy = rc.DeepCopy()
355370
copy.Spec = rcvb2.RedisClusterSpec{}
356371
copy.Status = status
357-
return common.UpdateStatus(ctx, r.Client, copy)
372+
return true, common.UpdateStatus(ctx, r.Client, copy)
358373
}
359-
return nil
374+
return false, nil
360375
}
361376

362377
// SetupWithManager sets up the controller with the Manager.

internal/controllerutil/controller_common.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,9 @@ func RequeueECheck(ctx context.Context, err error, msg string, keysAndValues ...
3939
}
4040
return RequeueE(ctx, err, msg, keysAndValues...)
4141
}
42+
43+
func Requeue() (reconcile.Result, error) {
44+
return reconcile.Result{
45+
Requeue: true,
46+
}, nil
47+
}

0 commit comments

Comments
 (0)