Files
Agent-System/internal/server/notification_reminder_loop.go
T
weichen a9c9a9182e refactor(server): remove 24 mirrored Runtime fields via nil-safe accessors; fix Shutdown-vs-background-loop DATA RACE and goose 00071 duplicate version
- Server no longer mirrors app.Runtime services (gov/svc/pwSvc/...): 574 call sites now use accessors in runtime_accessors.go
- backgroundLoop (mutex+sync.Once) stops sweeper/publisher/reminder/wsGC goroutines race-free (baseline 44161d2a reproduced DATA RACE; now green under -race)
- goose 00071 duplicate (dialogue merge 1da17a28 brought two 00071): context-conflict-adjudications renumbered to 00072; dev DB applied only through 00070 so zero data migration
- task_finalize tests build minimal app.Runtime; test injection via serverTestOverrides + setOverride* (explicit-nil markers for fail-closed cases)
2026-09-25 13:17:22 +00:00

47 lines
949 B
Go

package server
import (
"context"
"log/slog"
"time"
)
const defaultReminderPollInterval = 15 * time.Minute
func (s *Server) startNotificationReminderLoop() {
if s == nil || s.notifySvc() == nil || !s.notifySvc().Available() {
return
}
stopCh, ok := s.reminderLoop.start()
if !ok {
return
}
go func() {
ticker := time.NewTicker(defaultReminderPollInterval)
defer ticker.Stop()
s.runStageAdvanceReminders(context.Background())
for {
select {
case <-stopCh:
return
case <-ticker.C:
s.runStageAdvanceReminders(context.Background())
}
}
}()
}
func (s *Server) runStageAdvanceReminders(ctx context.Context) {
if s.notifySvc() == nil || !s.notifySvc().Available() {
return
}
n, err := s.notifySvc().ProcessStageAdvanceReminders(ctx)
if err != nil {
slog.Warn("stage advance reminder scan failed", "error", err)
return
}
if n > 0 {
slog.Info("stage advance 24h reminders sent", "count", n)
}
}