fix(idlewatcher): don't adopt a dependency's config on reload - #263
Conversation
NewWatcher reuses an existing watcher by key and copies the incoming IdlewatcherConfigBase over the stored one when the incoming idle timeout is positive. neverTick, which marks a dependency that must never auto-sleep, is math.MaxInt64 and so passes that check. A route that is both its own idle route and another route's dependency therefore loses its own idle_timeout, wake_timeout, stop_method and stop_signal to the dependency's inherited base, depending on the order NewWatcher is called in. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthrough
ChangesIdle watcher reload behavior
Estimated code review effort: 1 (Trivial) | ~5 minutes Merge Risk: ⚪ Minimal · up to Idle watcher reloads now preserve route settings when dependency-generated neverTick configurations are encountered, while real route configuration updates continue to apply. No current merge-blocking risk is identified. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
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. A rabbit checks the watcher’s beat Comment |
|
|
Thanks~ |



A route that is both its own idle route and another route's dependency can silently lose its own idlewatcher settings.
The bug
NewWatcherreuses an existing watcher by key and copies the incoming base config over the stored one:Dependencies are given
IdleTimeout = neverTickso they never auto-sleep, andneverTickistime.Duration(1<<63 - 1)— positive, so it passes that check.When such a route is resolved as a dependency,
NewWatcheris called a second time for the same container key with the dependency-synthesized config, and the route's realidle_timeout,wake_timeout,stop_methodandstop_signalare replaced by the dependency's inherited base. Which config wins depends on the orderNewWatcherhappens to be called in.The fix
Preserve a route-owned base config when a dependency config arrives, while still adopting updated settings for dependency-only watchers:
A genuine positive route config is still adopted, including when a dependency-only watcher becomes a route-owned watcher. Existing handling of incoming zero and negative idle timeouts is unchanged.
Tests
Regression coverage checks all base settings: idle timeout, wake timeout, stop timeout, stop method, and stop signal.
Verification
Validated on Linux/arm64 with Go 1.27.1 using the PR's pinned submodules:
shadowtree test ./internal/idlewatcher/... -count=1passed.shadowtree test-race ./internal/idlewatcher/... -count=1passed.git diff --checkpassed.No dependency changes or platform shims were needed. Tests use the existing fake-provider harness, not live Docker containers.
🤖 Generated with Claude Code
Note
Stop
idlewatcherreload from adopting dependency config over route-owned timeoutChanges the reload condition in watcher.go so a dependency-synthesized
neverTickconfig no longer overwrites an existing watcher that already has a route-owned idle timeout. Genuine reloads with a positive timeout or non-neverTicksettings still adopt the new config, and dependency-only watchers still receive refreshed settings.Adds table-driven tests in watcher_dependencies_test.go covering route-owned reloads, dependency-only reloads, and dependency-setting refresh through a parent reload.
Macroscope summarized 7807dfa.
Summary by CodeRabbit
Bug Fixes
Tests