MCPcopy
hub / github.com/PatchMon/PatchMon / runServiceLoop

Function runServiceLoop

agent-source-code/cmd/patchmon-agent/commands/serve.go:76–629  ·  view source on GitHub ↗

runServiceLoop is the main service loop. stopCh signals shutdown (nil = run forever on Unix)

(stopCh <-chan struct{})

Source from the content-addressed store, hash-verified

74
75// runServiceLoop is the main service loop. stopCh signals shutdown (nil = run forever on Unix)
76func runServiceLoop(stopCh <-chan struct{}) error {
77 // When running as Windows service, allow a brief delay for system initialization
78 // (network, filesystem) to be ready after SCM starts the process. This addresses
79 // first-start issues where the report task would not run.
80 if runtime.GOOS == "windows" && isWindowsService() {
81 logger.Info("Windows service detected, waiting briefly for system initialization...")
82 time.Sleep(5 * time.Second)
83 }
84
85 // Load credentials with retry on Windows service (first start may race with installer)
86 var loadErr error
87 for attempt := 0; attempt < 3; attempt++ {
88 loadErr = cfgManager.LoadCredentials()
89 if loadErr == nil {
90 break
91 }
92 if runtime.GOOS == "windows" && isWindowsService() && attempt < 2 {
93 logger.WithError(loadErr).Warn("Failed to load credentials, retrying in 2s...")
94 time.Sleep(2 * time.Second)
95 } else {
96 return loadErr
97 }
98 }
99 if loadErr != nil {
100 return loadErr
101 }
102
103 httpClient := client.New(cfgManager, logger)
104 ctx := context.Background()
105
106 // Get api_id for offset calculation
107 apiID := cfgManager.GetCredentials().APIID
108
109 // Load interval from config.yml (with default fallback)
110 intervalMinutes := cfgManager.GetConfig().UpdateInterval
111 if intervalMinutes <= 0 {
112 // Default to 60 if not set or invalid
113 intervalMinutes = 60
114 logger.WithField("interval", intervalMinutes).Info("Using default interval (not set in config)")
115 } else {
116 logger.WithField("interval", intervalMinutes).Info("Loaded interval from config.yml")
117 }
118
119 // Fetch interval from server and update config if different
120 if resp, err := httpClient.GetUpdateInterval(ctx); err == nil && resp.UpdateInterval > 0 {
121 if resp.UpdateInterval != intervalMinutes {
122 logger.WithFields(logutil.SanitizeMap(map[string]interface{}{
123 "config_interval": intervalMinutes,
124 "server_interval": resp.UpdateInterval,
125 })).Info("Server interval differs from config, updating config.yml")
126
127 if err := cfgManager.SetUpdateInterval(resp.UpdateInterval); err != nil {
128 logger.WithError(err).Warn("Failed to save interval to config.yml")
129 } else {
130 intervalMinutes = resp.UpdateInterval
131 logger.WithField("interval", intervalMinutes).Info("Updated interval in config.yml")
132 }
133 }

Callers 3

ExecuteMethod · 0.85
runAsServiceFunction · 0.85
runAsServiceFunction · 0.85

Calls 15

StartMethod · 0.95
StopMethod · 0.95
ResetMethod · 0.95
wsLoopFunction · 0.85
reportIntegrationStatusFunction · 0.85
sendReportFunction · 0.85
newComplianceSchedulerFunction · 0.85
updateAgentFunction · 0.85
refreshDockerInventoryFunction · 0.85
runPatchFunction · 0.85
toggleIntegrationFunction · 0.85

Tested by

no test coverage detected