Skip to content

fix(chk): let healthy keeper reconciles complete - #2059

Closed
KyriosGN0 wants to merge 1 commit into
Altinity:0.27.3from
KyriosGN0:agent/fix-chk-inprogress
Closed

fix(chk): let healthy keeper reconciles complete#2059
KyriosGN0 wants to merge 1 commit into
Altinity:0.27.3from
KyriosGN0:agent/fix-chk-inprogress

Conversation

@KyriosGN0

Copy link
Copy Markdown

What changed

  • remove the unconditional 10-second wait from same-size CHK reconciles while preserving Raft settle waits for scale-up and scale-down
  • propagate reconcile-start and completion status update errors to controller-runtime
  • emit completion events and metrics only after Completed is persisted
  • add unit coverage for settle-delay selection and status persistence failures
  • add a three-node CHK regression that verifies status and task histories remain stable beyond the former reconcile window

Root cause

The CHK reconciler waited 10 seconds even when Keeper membership had not changed. More importantly, status persistence errors from both reconcile start and finalization were discarded. A failed final status write could therefore leave the resource at InProgress with taskIDsStarted growing and no taskIDsCompleted, while the controller still reported successful reconciliation.

Impact

Healthy Keeper installations can converge to and remain at Completed. Transient status update failures are returned to controller-runtime for retry instead of being silently treated as success. No CRD or public configuration changes are required.

Fixes #2035

Validation

  • go test -count=1 -vet=off -race ./pkg/controller/chk/... ./pkg/controller/common/statefulset/... ./pkg/apis/clickhouse-keeper.altinity.com/v1/...
  • go test -vet=off ./pkg/controller/...
  • python3 -m py_compile tests/e2e/test_operator.py
  • git diff --check upstream/0.27.3...HEAD

The cluster-dependent e2e scenario was added but not run locally. Standard Go 1.26 vet remains affected by pre-existing dynamic logging format warnings.

Signed-off-by: AvivGuiser <avivguiser@gmail.com>
@KyriosGN0
KyriosGN0 marked this pull request as ready for review August 7, 2026 17:08
@KyriosGN0

Copy link
Copy Markdown
Author

hey @alex-zaitsev could you please take a look here? Thanks!

alex-zaitsev added a commit that referenced this pull request Aug 22, 2026
Refuse disruptive STS changes when Ready members are at majority, wait Ready
only when live quorum exists, abort on STS wait failure, and drop the same-size
10s settle sleep while propagating status persist errors. Fixes #2069; partial #2059.

Co-authored-by: Cursor <cursoragent@cursor.com>
alex-zaitsev added a commit that referenced this pull request Aug 22, 2026
Refuse disruptive STS changes when Ready members are at majority, wait Ready
only when live quorum exists, abort on STS wait failure, and drop the same-size
10s settle sleep while propagating status persist errors. Fixes #2069; partial #2059.

Co-authored-by: Cursor <cursoragent@cursor.com>
sunsingerus pushed a commit that referenced this pull request Sep 7, 2026
Refuse disruptive STS changes when Ready members are at majority, wait Ready
only when live quorum exists, abort on STS wait failure, and drop the same-size
10s settle sleep while propagating status persist errors. Fixes #2069; partial #2059.

Co-authored-by: Cursor <cursoragent@cursor.com>
sunsingerus added a commit that referenced this pull request Sep 7, 2026
The six commits from PR #2070 were rebased onto 0.27.4 (c1c1d47..4ebf303) and
reworked on top. This merge records the original PR branch as a parent so the
contribution is credited; the tree is unchanged.

Conflict resolution: 0.27.4's finalizeCR keeps its aborted guard, which skips the
completion bookkeeping when normalize refuses a spec. The PR's persistReconcileCompleted
called ReconcileComplete()/SetAncestor unconditionally and would have reverted it. Both
intents are kept - the guard, and the PR's status-write error propagation (#2059).

Reworked on top of the original PR:
- a quorum-headroom floor: below 3 members there is no headroom to protect, so the
  gate only forbade the roll. A 2-node CHK could never be rolled again once upgraded
- peer Ready counts are re-read during the wait; they were frozen at reconcile start,
  so the wait could never observe the recovery it was waiting for
- a failed StatefulSet Get is surfaced rather than undercounting Ready, which flipped
  the pass to bootstrap and disabled both the gate and the Ready wait
- membership is max(desired, ancestor), so a downscale keeps gating at the live
  Raft member count
@alex-zaitsev

alex-zaitsev commented Sep 9, 2026

Copy link
Copy Markdown
Member

Thank you for your effort, we incorporated some of your proposals into a bigger PR.

Covered in #2070

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants