Skip to content

Commit 5059cf4

Browse files
committed
fix(agent): reduce reconcile churn with configurable retry interval
1 parent 37667bd commit 5059cf4

2 files changed

Lines changed: 39 additions & 5 deletions

File tree

internal/agent/reconciler.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ type ImpVMReconciler struct {
4646
// StartTimeout is how long a VM may remain in Starting before being
4747
// transitioned to Failed. Defaults to 5 minutes when zero.
4848
StartTimeout time.Duration
49+
// RetryInterval is how long the agent waits before retrying high-churn
50+
// reconcile paths (Starting and Terminating stop errors). Defaults to 5s.
51+
RetryInterval time.Duration
4952
// Recorder emits lifecycle events for VM completion/failure.
5053
Recorder record.EventRecorder
5154
}
@@ -104,6 +107,13 @@ func (r *ImpVMReconciler) startTimeout() time.Duration {
104107
return 5 * time.Minute
105108
}
106109

110+
func (r *ImpVMReconciler) retryInterval() time.Duration {
111+
if r.RetryInterval > 0 {
112+
return r.RetryInterval
113+
}
114+
return 5 * time.Second
115+
}
116+
107117
func (r *ImpVMReconciler) handleStarting(ctx context.Context, vm *impdevv1alpha1.ImpVM) (ctrl.Result, error) {
108118
log := logf.FromContext(ctx)
109119
if vm.Status.StartedAt != nil {
@@ -112,7 +122,7 @@ func (r *ImpVMReconciler) handleStarting(ctx context.Context, vm *impdevv1alpha1
112122
return r.finishFailed(ctx, vm)
113123
}
114124
}
115-
return ctrl.Result{RequeueAfter: 2 * time.Second}, nil
125+
return ctrl.Result{RequeueAfter: r.retryInterval()}, nil
116126
}
117127

118128
func (r *ImpVMReconciler) handleScheduled(ctx context.Context, vm *impdevv1alpha1.ImpVM) (result ctrl.Result, err error) {
@@ -294,7 +304,7 @@ func (r *ImpVMReconciler) handleTerminating(ctx context.Context, vm *impdevv1alp
294304

295305
if err = r.Driver.Stop(ctx, vm); err != nil {
296306
log.Error(err, "Driver Stop failed — will retry")
297-
return ctrl.Result{RequeueAfter: 2 * time.Second}, err
307+
return ctrl.Result{RequeueAfter: r.retryInterval()}, err
298308
}
299309

300310
if r.Metrics != nil {

internal/agent/reconciler_test.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,10 @@ var _ = Describe("ImpVM Agent: Terminating → clears nodeName", func() {
217217
})
218218
})
219219

220-
var _ = Describe("ImpVM Agent: VMPhaseStarting → RequeueAfter 2s", func() {
220+
var _ = Describe("ImpVM Agent: VMPhaseStarting → RequeueAfter", func() {
221221
ctx := context.Background()
222222

223-
It("returns RequeueAfter=2s and does not mutate status", func() {
223+
It("returns RequeueAfter=5s by default and does not mutate status", func() {
224224
vm := &impdevv1alpha1.ImpVM{
225225
ObjectMeta: metav1.ObjectMeta{
226226
Name: "tc5-starting", Namespace: "default",
@@ -239,12 +239,36 @@ var _ = Describe("ImpVM Agent: VMPhaseStarting → RequeueAfter 2s", func() {
239239
NamespacedName: types.NamespacedName{Name: "tc5-starting", Namespace: "default"},
240240
})
241241
Expect(err).NotTo(HaveOccurred())
242-
Expect(result.RequeueAfter).To(Equal(2 * time.Second))
242+
Expect(result.RequeueAfter).To(Equal(5 * time.Second))
243243

244244
updated := &impdevv1alpha1.ImpVM{}
245245
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: "tc5-starting", Namespace: "default"}, updated)).To(Succeed())
246246
Expect(updated.Status.Phase).To(Equal(impdevv1alpha1.VMPhaseStarting))
247247
})
248+
249+
It("uses explicit RetryInterval when configured", func() {
250+
vm := &impdevv1alpha1.ImpVM{
251+
ObjectMeta: metav1.ObjectMeta{
252+
Name: "tc5-starting-override", Namespace: "default",
253+
Finalizers: []string{"imp/finalizer"},
254+
},
255+
Spec: impdevv1alpha1.ImpVMSpec{NodeName: testNode},
256+
}
257+
Expect(k8sClient.Create(ctx, vm)).To(Succeed())
258+
DeferCleanup(func() { k8sClient.Delete(ctx, vm) }) //nolint:errcheck
259+
260+
base := vm.DeepCopy()
261+
vm.Status.Phase = impdevv1alpha1.VMPhaseStarting
262+
Expect(k8sClient.Status().Patch(ctx, vm, client.MergeFrom(base))).To(Succeed())
263+
264+
r := newReconciler(NewStubDriver())
265+
r.RetryInterval = 9 * time.Second
266+
result, err := r.Reconcile(ctx, reconcile.Request{
267+
NamespacedName: types.NamespacedName{Name: "tc5-starting-override", Namespace: "default"},
268+
})
269+
Expect(err).NotTo(HaveOccurred())
270+
Expect(result.RequeueAfter).To(Equal(9 * time.Second))
271+
})
248272
})
249273

250274
var _ = Describe("ImpVM Agent: nodeName filter", func() {

0 commit comments

Comments
 (0)