Skip to content

refactor: retire deprecated ctrl.Result{Requeue: true} (6 sites) without stalling reconciles #18

Description

@CMGS

controller-runtime v0.23 deprecates Result.Requeue ("Use RequeueAfter instead"). We have 6 production sites:

  • hibernation/reconciler.go:135 (after finalizer-add Update)
  • cocoonset/reconciler.go:81 (after finalizer-add Update)
  • cocoonset/reconciler.go:131 (after drifted-main Delete)
  • cocoonset/reconciler.go:157 (after sub-agent/toolbox changes)
  • cocoonset/reconciler.go:191 (after main-agent Create)
  • cocoonset/suspend.go:38 (after pre-suspend main Create)

plus the res.Requeue assertion in hibernation/reconciler_test.go.

Why this was NOT mechanically swapped in the 2026-07-16 audit round

The naive "drop the requeue, rely on the watch" replacement is a stall bug for at least one site: cocoonset's For(&CocoonSet{}) is filtered by GenerationChangedPredicate, and a finalizer-add Update does not bump metadata.generation — the self-triggered watch event would be discarded and the reconcile would stall until an unrelated event or resync. The pod-mutation sites depend on what podRelevantChange passes for Create/Delete events, which needs verification per event type.

RequeueAfter: <tiny> preserves immediacy but bypasses the workqueue rate limiter; RequeueAfter: requeueInterval (5s) adds flat latency to the create/converge flow that PR #16 just optimized.

Proposed scope

Per-site replacement with verified event coverage:

  1. Sites whose self-mutation demonstrably re-triggers the watch (unfiltered For, predicate-passing pod events): return ctrl.Result{} and add a regression test that the follow-up reconcile actually fires.
  2. Sites filtered by GenerationChangedPredicate: keep an explicit requeue via RequeueAfter with a latency-neutral duration, or relax the predicate deliberately.
  3. Update the test assertion to the new signal.

Acceptance: no Result.Requeue usage; converge latency for create/suspend flows unchanged (bench per reconcile_bench_test.go); no reconcile stalls under the finalizer-add path with a filtered watch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions