Skip to content

refactor: replace deprecated Result.Requeue in controller reconcilers - #1346

Closed
christian-heusel wants to merge 2 commits into
kubeflow:notebooks-v2from
christian-heusel:chore/fix-requeue-deprecation
Closed

refactor: replace deprecated Result.Requeue in controller reconcilers#1346
christian-heusel wants to merge 2 commits into
kubeflow:notebooks-v2from
christian-heusel:chore/fix-requeue-deprecation

Conversation

@christian-heusel

@christian-heusel christian-heusel commented Aug 23, 2026

Copy link
Copy Markdown
Member

What / Why

controller-runtime deprecates reconcile.Result.Requeue in favor of RequeueAfter / returning an error. The dependency bump in #1306 moves the controller to controller-runtime v0.24.1, where staticcheck flags every Result{Requeue: true} usage as SA1019:

This setting is deprecated as it causes confusion and there is no good
reason to use it. When waiting for an external event to happen, either the
duration until it is supposed to happen or an appropriate poll interval
should be used, rather than an interval emitted by a ratelimiter whose
purpose it is to control retry on error.
Deprecated: Use `RequeueAfter` instead.

This PR removes all 16 usages in the controller reconcilers. The change is valid on the current v0.19.1 too, so it can land independently of #1306.

This is intentionally opened as a draft to agree on the approach before polishing. The mechanical part is settled; the open question is the logging tradeoff below.

Commit layout

  1. chore: bump Go dependencies in controller — a temporary cherry-pick of the controller dependency bump from chore: Bump golang dependencies in backend & controller #1306, included here only so this PR's CI exercises controller-runtime v0.24.1, i.e. a version where Result.Requeue is actually deprecated and staticcheck flags it. It is identical to the commit in chore: Bump golang dependencies in backend & controller #1306 and will drop out on rebase once chore: Bump golang dependencies in backend & controller #1306 merges into notebooks-v2.
  2. refactor: replace deprecated Result.Requeue … — the actual change under review.

Please review the second commit; the first is scaffolding.

Approach

The reconciler used Requeue: true in two distinct situations, handled differently:

Situation Count Old New Rationale
IsConflict(err) retry after an update 14 return Result{Requeue: true}, nil return Result{}, err A conflict is an error; returning it lets the workqueue rate-limiter handle retry-on-error — exactly what the deprecation note says that limiter is for. Preserves the identical rate-limited/backoff behavior.
Stale cache (owned ServiceAccount not yet cached) 2 return Result{Requeue: true}, nil return Result{}, nil We already Owns(&ServiceAccount{}), so the owned-object watch will requeue us — the existing code comments already say so. No explicit requeue needed.

mergeReconcileResult() no longer inspects the deprecated .Requeue field and merges purely on RequeueAfter; its unit test was updated to match.

Options considered

Option Requeue timing Logging Notes
A. return the error (this PR) immediate, rate-limited backoff — identical to Requeue: true conflict now logged at error level by controller-runtime Matches the deprecation's stated rationale; smallest behavioral change to timing.
B. RequeueAfter: <small const> fixed delay, no exponential backoff stays quiet (returns nil) Changes retry cadence; needs a somewhat arbitrary constant.
C. //nolint:staticcheck unchanged unchanged Keeps the deprecated API; just silences the linter.

🗣️ Discussion points

  1. Logging noise (main one). With option A, benign optimistic-concurrency conflicts — previously logged only at V(2) and returned as nil — now surface via controller-runtime's "Reconciler error" at error level (and bump the error metric). Is that acceptable, or do we prefer option B (RequeueAfter) to keep conflicts quiet at the cost of changing the retry cadence?
  2. Stale-cache sites. Is relying solely on the Owns(&ServiceAccount{}) watch to requeue acceptable, or would you rather keep an explicit short RequeueAfter as a safety net?
  3. Scope. Should this also convert k8s.io/apimachinery/pkg/util/httpstreamk8s.io/streaming/pkg/httpstream (the other SA1019 the bump surfaces), or keep that as a separate PR?

related: #1306

@google-oss-prow

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign andyatmiami for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@google-oss-prow
google-oss-prow Bot requested a review from andyatmiami August 23, 2026 11:52
@google-oss-prow google-oss-prow Bot added the area/v2 area - version - kubeflow notebooks v2 label Aug 23, 2026
Bump k8s.io libraries, controller-runtime, istio.io/api and
istio.io/client-go, and their transitive deps, to match the versions
used in workspaces/backend.

Also switch NewWebhookManagedBy/admission.Validator usage in
workspace_webhook.go and workspacekind_webhook.go to the typed API
instead of manually type-asserting runtime.Object.

Regenerate the WorkspaceKind CRD for new upstream corev1 fields.

Assisted-by: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Christian Heusel <christian@heusel.eu>
controller-runtime deprecates Result.Requeue in favor of RequeueAfter /
returning an error (see the v0.24.1 field docs). The dependency bump in
kubeflow#1306 moves the controller to a version where staticcheck flags every
usage as SA1019, so this proactively removes them (the change is valid on
the current controller-runtime v0.19.1 too).

This replaces every usage in the controller reconcilers:

- Conflict-retry sites now return the conflict error so the workqueue
  rate-limiter handles retry-on-error (its documented purpose), which
  preserves the same rate-limited backoff that Requeue: true provided.
- Stale-cache sites (ServiceAccount not yet in the cache) rely on the
  Owns(ServiceAccount) watch to requeue, matching the existing comments.
- mergeReconcileResult drops its .Requeue handling and now merges purely
  on RequeueAfter; its unit test is updated accordingly.

Tradeoff for discussion: conflict errors are now surfaced by
controller-runtime at error level rather than staying quiet at V(2).

Assisted-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Christian Heusel <christian@heusel.eu>
@christian-heusel
christian-heusel force-pushed the chore/fix-requeue-deprecation branch from 977f178 to 700cdec Compare August 23, 2026 11:58
@google-oss-prow google-oss-prow Bot added size/XL and removed size/M labels Aug 23, 2026
@github-project-automation github-project-automation Bot moved this from Needs Triage to Done in Kubeflow Notebooks Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/controller area - related to controller components area/v2 area - version - kubeflow notebooks v2 do-not-merge/work-in-progress size/XL

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant