Skip to content

feat: hot-reload YAML config without restarting the daemon (refs #424)#481

Draft
Copilot wants to merge 6 commits into
masterfrom
copilot/featurehot-reloading-yaml-config
Draft

feat: hot-reload YAML config without restarting the daemon (refs #424)#481
Copilot wants to merge 6 commits into
masterfrom
copilot/featurehot-reloading-yaml-config

Conversation

Copilot AI commented May 23, 2026

Copy link
Copy Markdown
Contributor
  • Explore codebase and identify all config options not yet hot-reloadable
  • internal/monitor.go: make TempSensorPollingRate dynamic — remove stored pollingRate field, reset ticker when config changes
  • internal/backend.go: update NewSensorMonitor call (drop pollingRate arg)
  • internal/controller/controller.go: add SetControlLoop to FanController interface + impl; protect controlLoop with controlLoopMu; make RpmPollingRate and AdjustmentTickRate tickers dynamic (reset on change)
  • internal/reload/reload.go: propagate per-fan config changes to fan objects on reload; rebuild and push control loop via SetControlLoop; add buildControlLoopForFan helper
  • internal/reload/reload_test.go: add SetControlLoop stub + stored config to fakeController/fakeFan; add 3 new tests for control loop update, algorithm change, and per-fan config propagation
  • Run tests — all 11 reload tests pass, controller tests pass
  • Address code review: use //nolint:staticcheck instead of //nolint:all

Copilot AI and others added 2 commits May 23, 2026 00:41
- Add ReadAndValidateConfig() to configuration package: reads a fresh
  viper instance, applies defaults/transformations/deprecations, and
  validates without touching the global CurrentConfig.
- Refactor applyTransformations/applyDeprecations to accept *Configuration
  so they can be called on arbitrary instances, not just the global one.
- Fix containsCmdFan/containsCmdSensors to use the passed-in config
  instead of the global CurrentConfig (was a latent bug in validateConfig).
- Extract makeDecodeHookOptions() and setDefaultValuesOnViper() helpers to
  share decode/default logic between LoadConfig and ReadAndValidateConfig.
- Add SetCurve(curves.SpeedCurve) to the FanController interface;
  implement it on DefaultFanController behind a sync.RWMutex so the
  running control loop and the hot-reload manager can race safely.
- New internal/reload package: ReloadManager watches the config file with
  fsnotify (debounced 500 ms) and responds to SIGHUP. On a valid change it
  updates CurrentConfig, recreates all SpeedCurve objects (PID state is
  intentionally reset), and calls SetCurve on each fan controller. If
  validation fails the daemon keeps running with the previous config.
- Wire ReloadManager into RunDaemon via the existing run.Group so it
  participates in clean shutdown.
- Promote fsnotify from indirect to direct dependency in go.mod.
- Add unit tests: internal/configuration/reload_test.go covers
  ReadAndValidateConfig (valid, invalid YAML, validation failure, no side
  effects on CurrentConfig); internal/reload/reload_test.go covers
  applyNewConfig, the full reload() pipeline (accept/reject paths), PID
  setpoint update end-to-end, and Run context-cancellation lifecycle."

Agent-Logs-Url: https://github.com/markusressel/fan2go/sessions/af1e65c2-a288-48c7-b16e-ee100ddb49d4

Co-authored-by: markusressel <14024504+markusressel@users.noreply.github.com>
- backend.go: make reload manager interrupt func a no-op; context
  cancellation already drives clean shutdown via rm.Run(ctx).
- reload.go: pass ctx to reload() so the apply step is skipped when
  the daemon is shutting down (check ctx.Done() before applyNewConfig).
- reload_test.go: add require.NoError for NewSpeedCurve in test setup;
  use type-asserted SetValue() instead of direct struct-field access to
  avoid bypassing the value mutex.

Agent-Logs-Url: https://github.com/markusressel/fan2go/sessions/af1e65c2-a288-48c7-b16e-ee100ddb49d4

Co-authored-by: markusressel <14024504+markusressel@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement hot reloading for YAML configuration file in fan2go feat: hot-reload YAML config without restarting the daemon (refs #424) May 23, 2026
Copilot AI requested a review from markusressel May 23, 2026 00:46
Copilot AI and others added 2 commits May 23, 2026 22:16
…ontrol algorithm)

Agent-Logs-Url: https://github.com/markusressel/fan2go/sessions/93f76bb2-2ae1-4066-a167-6872468e0a93

Co-authored-by: markusressel <14024504+markusressel@users.noreply.github.com>
…ated field access

Agent-Logs-Url: https://github.com/markusressel/fan2go/sessions/93f76bb2-2ae1-4066-a167-6872468e0a93

Co-authored-by: markusressel <14024504+markusressel@users.noreply.github.com>
@markusressel markusressel changed the base branch from feature/hot-reload-config-424 to master May 23, 2026 22:49
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