fix: stop committed resource controller reconcile storm - #1089
Conversation
setAccepted unconditionally wrote a new AcceptedAt timestamp and a time-varying StatusSummary on every call, causing a non-empty status patch even when the CR was already accepted for the current generation. The self-watch (EnqueueRequestForObject) fired on each patch, re-enqueuing every accepted cores commitment in a tight ~2s loop and keeping the workqueue depth permanently elevated around 80. Add an early-return guard in setAccepted that skips the patch when Ready=True/Accepted is already set for the current generation. Signed-off-by: Julius Clausnitzer <julius.clausnitzer@sap.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe committed resource controller skips redundant Accepted status patches when the condition is current. A test verifies the initial status update and confirms a second reconcile leaves the resource version unchanged. ChangesCommitted resource acceptance
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@internal/scheduling/reservations/commitments/committed_resource_controller_test.go`:
- Around line 1173-1176: Update the test setup around newTestCoresCR and the
first reconcile to set cr.Generation to 1 before creating the test client, then
assert that the accepted condition’s ObservedGeneration equals 1 after
reconciliation. Keep the existing condition assertions and test flow unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: b57c19c7-e446-4ab0-8fb7-912f482a2414
📒 Files selected for processing (2)
internal/scheduling/reservations/commitments/committed_resource_controller.gointernal/scheduling/reservations/commitments/committed_resource_controller_test.go
Set cr.Generation=1 before creating the test client so the fake object has a realistic generation, and assert that the accepted condition's ObservedGeneration equals 1 after the first reconcile. This ensures the guard in setAccepted correctly keys off the current generation. Signed-off-by: Julius Clausnitzer <julius.clausnitzer@sap.com>
Test Coverage ReportTest Coverage 📊: 70.3% |
## Release cortex v0.3.4 Release prep PR: #1094 ✅ ### Changes since v0.3.3 #### Bug Fixes - **Deep-copy capacity map to prevent informer cache corruption** — the capacity filter assigned hypervisor Status.Capacity map references directly into a local working map, then mutated those maps during free-resource calculations. Since the maps are shared with the controller-runtime informer cache, each scheduling pass permanently decremented cached capacity values, progressively starving scheduling until all hosts appeared full (#1065) - **Reset gauge metrics in reservation monitor to prevent stale values** — adds `Reset()` calls on `numberOfReservations` and `reservedResources` GaugeVecs before repopulating in `Collect`, preventing stale label combinations from persisting when reservations are deleted or change status (#1092) - **Stop committed resource controller reconcile storm** — `setAccepted` unconditionally wrote a new AcceptedAt timestamp and a time-varying StatusSummary on every call, causing a non-empty status patch even when the CR was already accepted. Adds an early-return guard that skips the patch when Ready=True/Accepted is already set for the current generation (#1089) #### Non-breaking Changes - Add History CRD documentation and multicluster guide link (#1091) - Update `github.com/prometheus/client_golang` to v1.24.1 (#1090) - Update `k8s.io/api`, `k8s.io/apimachinery`, `k8s.io/client-go` to v0.36.3 (#1086) - Update `github.com/sapcc/go-bits` (#1085) - Update `kube-prometheus-stack` to 87.19.2 (#1090) - Remove year from licensing section in readme (#1087) ### Version Bumps | Chart | Previous | New | |-------|----------|-----| | cortex (library) | 0.3.3 | 0.3.4 | | cortex-shim (library) | 0.1.9 | 0.1.10 | | cortex-nova | 0.0.83 | 0.0.84 | | cortex-cinder | 0.0.83 | 0.0.84 | | cortex-manila | 0.0.83 | 0.0.84 | | cortex-crds | 0.0.83 | 0.0.84 | | cortex-ironcore | 0.0.83 | 0.0.84 | | cortex-pods | 0.0.83 | 0.0.84 | | cortex-placement-shim | 0.1.9 | 0.1.10 |
setAccepted unconditionally wrote a new AcceptedAt timestamp and a time-varying StatusSummary on every call, causing a non-empty status patch even when the CR was already accepted for the current generation. The self-watch (EnqueueRequestForObject) fired on each patch, re-enqueuing every accepted cores commitment in a tight ~2s loop and keeping the workqueue depth permanently elevated around 80. Add an early-return guard in setAccepted that skips the patch when Ready=True/Accepted is already set for the current generation. --------- Signed-off-by: Julius Clausnitzer <julius.clausnitzer@sap.com> Signed-off-by: juliusclausnitzer <julius.clausnitzer@sap.com>
setAccepted unconditionally wrote a new AcceptedAt timestamp and a time-varying StatusSummary on every call, causing a non-empty status patch even when the CR was already accepted for the current generation. The self-watch (EnqueueRequestForObject) fired on each patch, re-enqueuing every accepted cores commitment in a tight ~2s loop and keeping the workqueue depth permanently elevated around 80.
Add an early-return guard in setAccepted that skips the patch when Ready=True/Accepted is already set for the current generation.