mirror of
https://github.com/henrygd/beszel.git
synced 2026-09-21 00:47:47 +02:00
Co-authored-by: Sven van Ginkel <svenvanginkel@icloud.com> Co-authored-by: xiaomiku01 <xiaomiku01@outlook.com>
61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"math/rand"
|
|
"time"
|
|
)
|
|
|
|
func (pm *MonitorManager) startMonitor(task *monitorTask) {
|
|
interval := time.Duration(task.config.Interval) * time.Second
|
|
if interval < time.Second {
|
|
interval = 30 * time.Second
|
|
}
|
|
delay := getStagger(interval.Milliseconds())
|
|
slog.Debug("starting monitor task", "target", task.config.Target, "delay", delay, "interval", interval)
|
|
go runMonitorSchedule(task.ctx, interval, delay, func() {
|
|
if _, allowed := task.resumeGuard.snapshot(); allowed {
|
|
task.runProbe(pm.probe)
|
|
}
|
|
})
|
|
}
|
|
|
|
// runMonitorSchedule owns only timing. Checks run serially, and slow checks
|
|
// naturally drop missed ticks rather than building an execution backlog.
|
|
func runMonitorSchedule(ctx context.Context, interval, delay time.Duration, run func()) {
|
|
timer := time.NewTimer(delay)
|
|
defer timer.Stop()
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-timer.C:
|
|
}
|
|
if ctx.Err() != nil {
|
|
return
|
|
}
|
|
run()
|
|
ticker := time.NewTicker(interval)
|
|
defer ticker.Stop()
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
if ctx.Err() != nil {
|
|
return
|
|
}
|
|
run()
|
|
}
|
|
}
|
|
}
|
|
|
|
// getStagger returns an initial delay between half an interval and one interval.
|
|
func getStagger(intervalMilli int64) time.Duration {
|
|
delay := rand.Intn(int(intervalMilli))
|
|
if delay < int(intervalMilli)/2 {
|
|
delay += int(intervalMilli) / 2
|
|
}
|
|
return time.Duration(delay) * time.Millisecond
|
|
}
|