Skip to content

fix(scheduler): honour HAMI_NODELOCK_EXPIRE when the flag is not set - #2721

Closed
IIITManjeet wants to merge 2 commits into
Project-HAMi:masterfrom
IIITManjeet:fix/nodelock-expire-env-precedence
Closed

fix(scheduler): honour HAMI_NODELOCK_EXPIRE when the flag is not set#2721
IIITManjeet wants to merge 2 commits into
Project-HAMi:masterfrom
IIITManjeet:fix/nodelock-expire-env-precedence

Conversation

@IIITManjeet

@IIITManjeet IIITManjeet commented Aug 18, 2026

Copy link
Copy Markdown

What type of PR is this?

/kind bug

What this PR does / why we need it:

The Helm chart exposes scheduler.nodeLockExpire, which sets the HAMI_NODELOCK_EXPIRE
environment variable on the scheduler extender. pkg/util/nodelock reads that variable in
its package init() and sets NodeLockTimeout from it.

start() then ran, unconditionally:

nodelock.NodeLockTimeout = config.NodeLockTimeout

config.NodeLockTimeout is populated by the --node-lock-timeout flag, which carries a
5m default whether or not the flag is passed. The environment-derived value was therefore
always discarded a few milliseconds after being set, and scheduler.nodeLockExpire had no
effect at all. The chart's own default of 5m masked this, so the setting only looks
broken once you change it.

This takes the flag only when it was explicitly provided, leaving precedence as flag, then
environment, then default.

Which issue(s) this PR fixes:

Fixes #2692

Special notes for your reviewer:

The issue suggests calling rootCmd.Flags().Changed("node-lock-timeout") from inside
start(). That does not compile:

cmd/scheduler/main.go:52:2: initialization cycle for rootCmd
        rootCmd refers to start
        start refers to rootCmd

rootCmd's RunE closure already refers to start, so start cannot refer back to
rootCmd. This PR reads the flag state in RunE, where cobra already supplies the
*cobra.Command, and passes it into start() as a parameter.

I verified behaviour by building the scheduler binary from master and from this branch
and reading its own startup log. "Set node lock timeout" is the effective value:

scenario before after
HAMI_NODELOCK_EXPIRE=7s, no flag 5m0s 7s
HAMI_NODELOCK_EXPIRE=7s + --node-lock-timeout=33s 33s 33s
neither set 5m0s 5m0s
HAMI_NODELOCK_EXPIRE=notaduration 5m0s 5m0s

Only the first row changes. TestApplyNodeLockTimeout covers the three precedence paths.

Per the hardware-validation gate in CONTRIBUTING, this change is scoped to the scheduler
extender and is covered by unit tests rather than GPU hardware.

Checks run locally (Go 1.26.6, linux/amd64):

  • go test -short --race ./pkg/... ./cmd/... — 37 packages ok, 0 failures
  • golangci-lint run ./... (v2.12.2, matching CI)
  • hack/verify-license.sh, hack/verify-import-aliases.sh, hack/verify-rbac.sh
  • go mod tidy — no change to go.mod or go.sum

#2692 also asks whether HAMI_NODELOCK_EXPIRE should remain at all, or whether the chart
should set --node-lock-timeout instead. I kept this PR to the precedence bug and left the
chart untouched, since that is an interface decision for the maintainers. Happy to follow
up either way.

Does this PR introduce a user-facing change?:

The scheduler's `scheduler.nodeLockExpire` Helm value (`HAMI_NODELOCK_EXPIRE`) now takes effect. Previously it was silently overwritten by the `--node-lock-timeout` default of 5m unless that flag was passed explicitly.

AI assistance disclosure: I used AI assistance (Claude Code) throughout this change: to understand the nodelock init path and how config.NodeLockTimeout is populated, to find that the fix suggested in the issue does not compile, to implement applyNodeLockTimeout, and to write cmd/scheduler/nodelock_timeout_test.go. It also ran the before/after binary comparison and the local checks listed above, and drafted the commit message and this description. I reviewed the change, understand the initialization-cycle constraint that shapes it, and am able to answer questions about it directly.

Summary by CodeRabbit

  • Bug Fixes
    • Node-lock timeout settings now use the configured default when no command-line override is provided.
    • Command-line timeout values continue to take precedence when explicitly specified.
  • Tests
    • Updated coverage to verify that the node-lock timeout flag and scheduler configuration share the correct default value.

The nodelock package reads HAMI_NODELOCK_EXPIRE in its package init, but
start() then assigned config.NodeLockTimeout over it unconditionally. That
value holds the --node-lock-timeout default of 5m whenever the flag is
absent, so the environment value was always discarded and the chart's
scheduler.nodeLockExpire setting had no effect.

Take the flag only when it was explicitly passed, leaving precedence as
flag, then environment, then default. The flag state is read in RunE and
passed into start(), because referring to rootCmd from start() makes Go
report an initialization cycle for rootCmd.

Signed-off-by: IIITManjeet <manjeetpathak2003@gmail.com>
@hami-robot hami-robot Bot added the kind/bug Something isn't working label Aug 18, 2026
@hami-robot

hami-robot Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: IIITManjeet
Once this PR has been reviewed and has the lgtm label, please assign wawa0210 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

@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 298891d3-5645-445b-b57d-1229f355b2ce

📥 Commits

Reviewing files that changed from the base of the PR and between 640467a and f2be4df.

📒 Files selected for processing (2)
  • cmd/scheduler/main.go
  • cmd/scheduler/nodelock_timeout_test.go

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The scheduler now uses nodelock.NodeLockTimeout as the node-lock-timeout flag default. Startup copies the configured timeout to the nodelock package. Tests verify the default and configuration synchronization.

Changes

Node-lock timeout handling

Layer / File(s) Summary
Timeout default and startup synchronization
cmd/scheduler/main.go, cmd/scheduler/nodelock_timeout_test.go
The flag uses nodelock.NodeLockTimeout as its default. Startup applies config.NodeLockTimeout without a flag-set indicator. The test verifies the default and synchronized configuration.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to f2be4

This localized change makes the configured node-lock expiration take effect while preserving explicit flag precedence; no actionable merge-blocking risk remains beyond normal checks and review.

Possibly related PRs

Suggested reviewers: ouyangluwei163

Poem

A rabbit sets the timeout right,
The environment keeps its value in sight.
The flag receives that value by default,
Startup applies it without a fault.
Tests check the setting with care.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the scheduler fix that preserves HAMI_NODELOCK_EXPIRE when the flag is not set.
Linked Issues check ✅ Passed The implementation preserves flag, environment, and 5-minute default precedence required by [#2692].
Out of Scope Changes check ✅ Passed The changes are limited to node-lock timeout initialization and its focused unit test.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread cmd/scheduler/main.go Outdated
if flagSet {
nodelock.NodeLockTimeout = config.NodeLockTimeout
return
}

@mesutoezdil mesutoezdil Aug 19, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 alternative: make the flag default nodelock.NodeLockTimeout in init, the env is already applied there by import order, then no bool threading is needed. also nothing else reads config.NodeLockTimeout, is the write back needed?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call on both. Done.

Flag default is now nodelock.NodeLockTimeoutmain imports pkg/util/nodelock, so its init() (and setupNodeLockTimeout, which reads HAMI_NODELOCK_EXPIRE) completes before this package registers flags. The default already carries the env value, so start() goes back to the plain unconditional assignment and applyNodeLockTimeout, the bool param and the Changed(...) call are gone. The write-back went too — as you say, nothing outside cmd/scheduler reads config.NodeLockTimeout.

Side benefit: PrintPFlags runs before start(), so the startup log used to print FLAG: --node-lock-timeout="5m0s" while the effective value was 7s. They agree now.

Rebuilt at both revisions and compared startup logs — Set node lock timeout is unchanged in all four cases (env only 7s, env+flag 33s, neither 5m0s, bad env 5m0s).

One visible trade-off: --help now shows an env-dependent default (7s when the chart sets scheduler.nodeLockExpire: 7s). I think showing the real default is better, but happy to pin it back if you'd rather.

TestApplyNodeLockTimeout had no function left to cover, so it's now TestNodeLockTimeoutFlagDefault, asserting the registered default is nodelock.NodeLockTimeout — re-hardcoding a duration there is exactly how #2692 comes back. Env parsing is already covered in pkg/util/nodelock/nodelock_test.go.

Sourcing the --node-lock-timeout default from nodelock.NodeLockTimeout
instead of a hard-coded 5m removes the need to inspect flag state at all.
cmd/scheduler imports pkg/util/nodelock, so nodelock's init, and with it
the read of HAMI_NODELOCK_EXPIRE, completes before this package registers
its flags. The default therefore already carries the environment value and
the assignment in start() is correct on its own, leaving precedence as
flag, then environment, then default.

This drops applyNodeLockTimeout, the bool parameter threaded through
start(), and the write-back to config.NodeLockTimeout, which nothing
outside cmd/scheduler reads.

It also makes the startup flag log honest: flag.PrintPFlags runs before
start(), so with HAMI_NODELOCK_EXPIRE=7s it reported 5m0s while the
effective timeout was 7s.

TestApplyNodeLockTimeout no longer has a function to cover and is replaced
by TestNodeLockTimeoutFlagDefault, which asserts the registered default is
nodelock.NodeLockTimeout. Parsing of the environment variable itself is
already covered by pkg/util/nodelock.

Suggested-by: mesutoezdil <mesutoezdil@users.noreply.github.com>
Signed-off-by: IIITManjeet <manjeetpathak2003@gmail.com>
@mesutoezdil

Copy link
Copy Markdown
Contributor

This is being closed because it does not comply with the contribution guidelines.

@IIITManjeet

Copy link
Copy Markdown
Author

Hey @mesutoezdil, apologies for breaking the contribution guidelines. Should I reframe it with my own wording for the reply and commit with a fresh PR or reopen it again with my updated reply.

@mesutoezdil

Copy link
Copy Markdown
Contributor

you MUST understand your codes, and should answer with your own words.
We do not have time and energy for llm answers.

@IIITManjeet

IIITManjeet commented Aug 19, 2026

Copy link
Copy Markdown
Author

yes @mesutoezdil agreed actually just asked llm to make it more professional like answer. Again, apologies for the llm drafted answer. If there is anything that I can help to undo my act, do let me know.
Thanks

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

Labels

kind/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

scheduler.nodeLockExpire / HAMI_NODELOCK_EXPIRE has no effect: overwritten by --node-lock-timeout flag default

2 participants