fix: AI Patrol frequency not obeying settings

Fixes #858

The patrol interval setting was not being properly applied due to:

1. ReconfigurePatrol() was setting the deprecated QuickCheckInterval field
   instead of the preferred Interval field

2. SetConfig() was comparing raw field values instead of using GetInterval()
   to compare effective intervals, causing change detection to fail

3. The API response was missing interval_ms, preventing the frontend from
   displaying the correct interval

Changes:
- Update StartPatrol() and ReconfigurePatrol() to use the Interval field
- Fix SetConfig() to use GetInterval() for interval comparison
- Add IntervalMs to PatrolStatusResponse and include it in the API response
This commit is contained in:
rcourtman 2025-12-18 21:33:50 +00:00
parent aff4e9b814
commit 862310c4c6
3 changed files with 18 additions and 17 deletions

View file

@ -265,18 +265,19 @@ func NewPatrolService(aiService *Service, stateProvider StateProvider) *PatrolSe
// SetConfig updates the patrol configuration
func (p *PatrolService) SetConfig(cfg PatrolConfig) {
p.mu.Lock()
oldInterval := p.config.QuickCheckInterval
oldInterval := p.config.GetInterval()
p.config = cfg
newInterval := cfg.GetInterval()
configCh := p.configChanged
p.mu.Unlock()
// Signal config change if patrol is running and interval changed
if configCh != nil && cfg.QuickCheckInterval != oldInterval {
if configCh != nil && newInterval != oldInterval {
select {
case configCh <- struct{}{}:
log.Info().
Dur("old_interval", oldInterval).
Dur("new_interval", cfg.QuickCheckInterval).
Dur("new_interval", newInterval).
Msg("Patrol interval updated, resetting ticker")
default:
// Channel full or not ready, config will be picked up on next cycle

View file

@ -358,13 +358,12 @@ func (s *Service) StartPatrol(ctx context.Context) {
// Configure patrol from AI config
patrolCfg := PatrolConfig{
Enabled: true,
QuickCheckInterval: cfg.GetPatrolInterval(),
DeepAnalysisInterval: 6 * time.Hour,
AnalyzeNodes: cfg.PatrolAnalyzeNodes,
AnalyzeGuests: cfg.PatrolAnalyzeGuests,
AnalyzeDocker: cfg.PatrolAnalyzeDocker,
AnalyzeStorage: cfg.PatrolAnalyzeStorage,
Enabled: true,
Interval: cfg.GetPatrolInterval(),
AnalyzeNodes: cfg.PatrolAnalyzeNodes,
AnalyzeGuests: cfg.PatrolAnalyzeGuests,
AnalyzeDocker: cfg.PatrolAnalyzeDocker,
AnalyzeStorage: cfg.PatrolAnalyzeStorage,
}
patrol.SetConfig(patrolCfg)
patrol.Start(ctx)
@ -404,13 +403,12 @@ func (s *Service) ReconfigurePatrol() {
// Update patrol configuration
patrolCfg := PatrolConfig{
Enabled: cfg.IsPatrolEnabled(),
QuickCheckInterval: cfg.GetPatrolInterval(),
DeepAnalysisInterval: 6 * time.Hour,
AnalyzeNodes: cfg.PatrolAnalyzeNodes,
AnalyzeGuests: cfg.PatrolAnalyzeGuests,
AnalyzeDocker: cfg.PatrolAnalyzeDocker,
AnalyzeStorage: cfg.PatrolAnalyzeStorage,
Enabled: cfg.IsPatrolEnabled(),
Interval: cfg.GetPatrolInterval(),
AnalyzeNodes: cfg.PatrolAnalyzeNodes,
AnalyzeGuests: cfg.PatrolAnalyzeGuests,
AnalyzeDocker: cfg.PatrolAnalyzeDocker,
AnalyzeStorage: cfg.PatrolAnalyzeStorage,
}
patrol.SetConfig(patrolCfg)

View file

@ -1956,6 +1956,7 @@ type PatrolStatusResponse struct {
ResourcesChecked int `json:"resources_checked"`
FindingsCount int `json:"findings_count"`
Healthy bool `json:"healthy"`
IntervalMs int64 `json:"interval_ms"` // Patrol interval in milliseconds
Summary struct {
Critical int `json:"critical"`
Warning int `json:"warning"`
@ -1997,6 +1998,7 @@ func (h *AISettingsHandler) HandleGetPatrolStatus(w http.ResponseWriter, r *http
ResourcesChecked: status.ResourcesChecked,
FindingsCount: status.FindingsCount,
Healthy: status.Healthy,
IntervalMs: status.IntervalMs,
}
response.Summary.Critical = summary.Critical
response.Summary.Warning = summary.Warning